Andy's observations as he continues to attempt to know all that is .NET...

Monday, July 03, 2006

.NET Generics and static methods

Been playing around with generics a bit more and have discovered something a little strange. When you run it you will see that you get the same result even though you instantiate the generic method with two different types that have the opposite functionality. If you know how generics work under the covers then I guess you will think I wouldn\'t be that stupid to write the code below, but If you are not completely up to speed with how it is implemented in the CLR then you may think the behaviour below is a little strange.


 

using System.Collections.Generic;

using System.Text;

namespace Constraints

{

public class A

{

public static bool operator ==(A lhs, A rhs)

{ return true; }


 

public static bool operator !=(A lhs, A rhs)

{ return false; }

}

public class B : A

{

public static bool operator ==(B lhs, B rhs)

{ return false;}


 

public static bool operator !=(B lhs, B rhs)

{ return true; }


 

}

class Program

{

public static void PerformOperation<T>(T lhs , T rhs ) where T:A

{

if (lhs == rhs)

{

Console.WriteLine(“Equal...”);

}

else

{

Console.WriteLine(“Not Equal...”)

}

}

static void Main(string[] args)

{

    A v1 = new A();

A v2 = new A();

PerformOperation<A>(v1, v2);

B v3 = new B();

B v4 = new B();

PerformOperation<B>(v3, v4);

}

}

In fact the C# compiler tries to stop you falling into this trap with a generic method with no constraints. The code below will not compile, the reason being the way in which genercis have been implemented. In .NET a generic method or type are constructed using common piece of IL using special generic IL instructions. All it needs to be know at compile time is which method to call to perform a piece of functionality, the binding to the final implementation either happens at JIT time for valuetypes or using runtime polymorphism in the case of ref types. For static methods and non virtual methods the binding happens when the generic method or type is compiled only the correct specific behaviour is used if the methods are polymorphic, or you supply the same type as defined by the constraint and not a more specialised version. It is for this reason that the C# compiler will not compile the code below as it will always perform an object comparison ( E.g. Reference equality ) even if the method is called PerformOperation<string>( string1 , string2)

public static void PerformOperation<T>(T lhs , T rhs )

{

if (lhs == rhs)

{

Console.WriteLine(“Equal...”);

}

else

{

Console.WriteLine(“Not Equal...”;)

}

}

What I’m failing to understand is why in my case it allows the compilation since it basically suffers the same issue. Perhaps generic methods should not be allowed to use non polymorphic methods.

No comments:

About Me

My photo
Im a freelance consultant for .NET based technology. My last real job, was at Cisco System were I was a lead architect for Cisco's identity solutions. I arrived at Cisco via aquisition and prior to that worked in small startups. The startup culture is what appeals to me, and thats why I finally left Cisco after seven years.....I now filll my time through a combination of consultancy and teaching for Developmentor...and working on insane startups that nobody with an ounce of sense would look twice at...