Friday, December 25, 2015

Generic Delegates in C#

In today's post, we will be discussing generic delegates in C#.

Generic Delegates

Previously, I talked about basics of delegates here. In that example, we used the Employee class for our delegate. The arguments of Employee type were hard-coded and the delegate could not be used with any other data type.

Generic Delegates in C#


With generic delegates we can make the delegate to use a generic type and be flexible with the actual type being used in the delegate.
Let's try to understand this with an example:

Suppose, we have a Person class:

public class Person
{
    public int Id { get; set; }
}


And an Employee class like this:

public class Employee : Person
{
    //Employee properties
}

So for comparing any class objects, let's have a generic delegate type:

public delegate bool AreEqual<T>(T a, T b);

For the actual instance, we can have any class like this:

bool AreSamePerson<T>(T a, T b) where T: Person
{
     ...
}

As we discussed constraints last week here, by having constraints we will be able to use the specific properties of Person class in our method definition.

So let's put them all together to see how it works:

public delegate bool AreEqual<T>(T a, T b);

static void Main(string[] args)
{
      var employeeA = new Employee() {Id = 1};
      var employeeB = new Employee() {Id = 2};
      var employeeC = new Employee() {Id = 1};

      AreEqual<Employee> IsEmployeeSame = 
        new AreEqual<Employee&gt(AreSamePerson<Employee>);

      Console.WriteLine(IsEmployeeSame(employeeA, employeeB));  
         //false
      Console.WriteLine(IsEmployeeSame(employeeA, employeeC));  
         //true

      Console.ReadLine();
}

static bool AreSamePerson<T>(T a, T b) where T: Person
{
     return (a.Id == b.Id);
}


So here we created three employees and compared them. We saw how the generic delegate can take any method (with appropriate signature) and can be used in our code. For delegate instances, we can have different methods (maybe with different constraints) which can be used with the delegate. This way we can generalize our generics and use them.

I can have separate method for IsEmployeeSame and IsPersonSame. If I want to add a new type, for example, Manager deriving from Person and I want it to use AreSamePerson to compare, I can do that or if I want to write a new AreManagerEqual (with Manager type) method, I can also do that.

Conclusion

So in this post, we saw how generic delegates can be useful to us along with an example. The flexibility it provides can help us in different situations.

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 :)


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 :)


Thursday, December 10, 2015

Generics in C#

Generics were introduced in C# 2.0 and were the most powerful feature of C# 2 at that time. They allow type and method parameterization in terms of the types they interact with.

Generics

Generics allow classes and methods to have more functionality as compared to what they could do without generics. In order to understand their power, let's take a look at some code without generics. We will then apply generics and see how they can help us.

Suppose, we have a simple method like this:

private static bool AreEqual(int a, int b)
{
     return a == b;
}

We can use this method in our code anywhere:

var x = AreEqual(10, 11);

It works fine as long as the application is limited to use only integers. Suppose, we want to use another type, for e.g. string for similar method. In order to do that, we will have two options (pre C# 2.0):
i) Create a new method AreEqual() which takes string arguments,
ii) Change AreEqual() method to have parameters of type object.

First solution will lead to code duplication for each and every newly added type.
Second solution will lead to casting of the objects each and every time, which might lead to performance issues. Also, by casting to object, we loose compile time type safety which may lead to run-time exceptions.

So now let's take a look at how we can simplify it using generics:

private static bool AreEqualGeneric<T>(T a, T b)
{
     return a.Equals(b);
}

So now we can use the generic method like this:
var y = AreEqualGeneric<int>(11, 11);

var z = AreEqualGeneric<string>("A", "B");

As you can see we are able to use the same method with different parameter types. So now we are able to write generic code one-time as well as have compile time type safety.

Conclusion

We saw how generics help us decouple logic from data type. In future posts, I will be covering some more on generics in C#.
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 :)


Thursday, December 3, 2015

Value vs Reference Types in C#

In today's blog post, I will be discussing the difference between value and reference types. There are certain misconceptions among people about the differences between the two.

Whenever there is a discussion on value vs reference types in C#, there are two user defined data types that come to mind: structs and classes. A struct is a value type and a class is a reference type. Let's understand their differences one by one.

Value Types

Suppose, we have a struct like this:

struct S
{
    private int x;
    private int y;
    //code...
}

When we create an instance of this struct, the memory is allocated on the stack and only one space is created in the memory for the instance.

S instance = new S();

The space for instance gets allocated on the stack.
If we do,

S instance2 = instance;

A new instance called instance2 is created (on stack) and is completely independent of the instance variable's value.
So when we pass a value type as a method parameter, it comes as a complete separate copy. Any changes to it are not reflected back in the caller code.

Reference Types

Suppose, we have a class like this:

class C
{
    private int x;
    private int y;
    //code...
}

When we create an instance of this class, 2 memory allocations happen: the variable is stored on the stack and object is stored on the heap.

C classInstance = new C();

So here classInstance variable is stored on stack and the actual object is stored on the heap. The classInstance variable simply refers to the object on the heap.

If we do,

C classInstance2 = classInstance;

classInstance2 is a new variable (created on stack) and it points to the same object (on heap) as referred by classInstance variable. So if we make any changes in the object using classInstance2 variable, the changes are reflected in classInstance variable's object too (because it's same). If I change the value of classInstance2.x, then classInstance.x is also changed. However, if I update the classInstance2 to refer to something else, for example if we set,

classInstance2= null;

It won't affect classInstance variable because we simply update the classInstance2 variable to point to a null reference. So when we pass objects like this to methods, the changes made to the object by the callee method are reflected back in the caller method. However, if we update the reference itself, that's not reflected back.

Ref Keyword

If in case, we want to update the reference too, we can use the ref keyword.

void Method1(ref C classInstance3)
{
    classInstance3 = null;
}

Method1(ref classInstance);

In this scenario, classInstance will be set to null by the callee method.

Conclusion

So we saw the differences between value and reference types in this article. We also saw that stack stores reference portion of reference-typed local variables and parameters and value typed local variables which are not part of a reference type. And heap stores content of reference type objects and anything inside a reference type object. So a generic statement like all value types are stored on stack might not be correct all the time as value types which are inside reference type objects are stored on heap.

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 :)