Consider the following generic method :
public static bool AreEqual<T>(T instance1, T instance2)
{
return instance1.Equals(instance2);
}
If we invoke the above method using following statement and look at the generated IL code
Console.WriteLine(AreEqual<int>(5,5));
IL Code
AreEqual:
IL_0000: nop
IL_0001: ldarga.s 00
IL_0003: ldarg.1
IL_0004: box 01 00 00 1B
IL_0009: constrained. 01 00 00 1B
IL_000F: callvirt System.Object.Equals
IL_0014: stloc.0 // CS$1$0000
IL_0015: br.s IL_0017
IL_0017: ldloc.0 // CS$1$0000
IL_0018: ret
In the IL code we can see that the call to method equal is getting redirected to Object’s equals method and the input parameters are getting boxed. Imagine if this method is getting invoked for multiple value types and the kind of negative performance impact it have on application performance because of the “box” operation.
In order to avoid the boxing operation, we can add an explicit constraint on the type parameter wherein the parameter is of type [IEquatable
public static bool AreEqual<T>(T instance1, T instance2) where T : IEquatable<T>
{
return instance1.Equals(instance2);
}
Console.WriteLine(AreEqual<int>(5, 5));
AreEqual:
IL_0000: nop
IL_0001: ldarga.s 00
IL_0003: ldarg.1
IL_0004: constrained. 02 00 00 1B
IL_000A: callvirt 12 00 00 0A
IL_000F: stloc.0 // CS$1$0000
IL_0010: br.s IL_0012
IL_0012: ldloc.0 // CS$1$0000
IL_0013: ret
As we can see that by constraining the type parameter to be of type IEquatable, we have avoided the boxing operation. So does that mean generic collections like List