Sunday, December 20, 2015

Constraints on Type Parameters in Generics in C#

In today's blog post, we will be discussing about constraints on type parameters in Generics in C#.

Constraints On Type Parameters

We saw a simplistic use of generics last week here. We saw how generics can help us re-use our code as well as have compile time type safety. In our generics example, we used the .Equals() method which is part of the Object class. The Object class, as we all know, is the ultimate base class of all the classes in .NET framework.

Constraints on Type Parameters in Generics


If we want to restrict the types that we want our Generic class/ method should be able to operate on, we can use constraints. Also, by adding the constraint, we can use the specific behavior/ properties that the constraining type exposes inside our generic method/ class. Constraints are specified using the "where" keyword.

Let's again have our favorite Employee class:

public class Employee
{
    public string Name { get; set; }
    public int EmployeeId { get; set; }
    public decimal Salary { get; set; }
}

Next, let's have a generic method with a constraint of type Employee class:

private static bool AreEqualGeneric<T>(T x, T y) where T:Employee
{
    return (x.EmployeeId == y.EmployeeId) ? true : false;
}

As you can see, by adding the constraint of Employee class we are able to access EmployeeId inside our generic method. Similarly, if there was any public method on the Employee class, we could have accessed that too. Also, we can now use this method only for an object of Employee class (or any derived class of Employee).

Now, let's use our generic method:

static void Main(string[] args)
{
      var employee1 = new Employee()
      {
          EmployeeId = 1,
          Name = "Abhi"
      };
      var employee2 = new Employee()
      {
          EmployeeId = 1,
          Name = "Abhi"
      };

      var isObjRefEqual = employee1.Equals(employee2);
      var isEmployeeIdEqual = 
         AreEqualGeneric(employee1, employee2);
      Console.WriteLine(
       String.Format("isObjRefEqual = {0}", isObjRefEqual));
      Console.WriteLine(
       String.Format("isEmployeeIdEqual = {0}",isEmployeeIdEqual));
      Console.ReadLine();
}

So, here we created 2 employees with same data. First, we compare the object references which turns out to be false because they both are pointing to different objects. When we use the generic method for comparison, we only compare EmployeeIds, so we get a True.

The generics constraints are often useful when we have a base class and multiple derived classes and we want to operate on the properties/ behavior exposed by the base class. We simply add the constraint for base class and then use any of the derived types as parameters to use the generic method/ class.

Conclusion

The constraints are a powerful addition to generics and help us write code that is more specific, as per our needs. By adding the constraints, we tell the compiler that these are the acceptable types for our generic class/ method. And as a result we are able to use that type to write the code specifically for that type.

For future updates to my weekly blog, please subscribe to my blog via the "Subscribe To Weekly Post" feature at the right and follow me on Twitter. Until then Happy Coding :)


No comments:

Post a Comment