LA.NET [EN]

Jan 02

Having fun with generics – part II

Posted in Uncategorized      Comments Off on Having fun with generics – part II

This is one of those things which might really make you go mad. Ok, let”s start with a non-generic class. What will happen when you try to build a program that has this class:

class Test
{
 public bool TestMethod(string par){ … }
 public bool TestMethod(string par) { … }
}

As you expect, you”ll get an error saying that type test already defines a member called TestMethod since you”ve already defined a method with the same name and the same parameters (both methods expect only a parameter of type string). But what will happen when you build the following class:

class Test<T>
{
 public bool TestMethod(T par){ Console.WriteLine(“T”); return true;}
 public bool TestMethod(string par){ Console.WriteLine(“string”); return true;}
}

Well, not sure about you, but I really thought that the C# compiler would at least throw a warning saying that there might be some problems with the 2nd method definition. Guess what: it didn”t. it compiled without any warnings. So I went on and run the following code:

Test<int> t = new Test<int>();
t.TestMethod(10);
t.TestMethod(“10”);
Console.ReadLine();

It worked as expected and I saw the following in the consolde:

T
string

Perfect! It makes sense. Now, how about this:

Test<string> t = new Test<string>();
t.TestMethod(“10”);
Console.ReadLine();

If you said string, you”re right. In these cases, the method that expects a parameter T will never be called. I expected to get an error saying that the overload method was incorrect, but i didn”t get any. I thought that compilation would run without any problems. It did. At runtime, i was really convinced that i”d get an error; I didn”t. I”ve even added this code to my console app:

Type tp = t.GetType();
MethodInfo[] methods = tp.GetMethods();
foreach( MethodInfo info in methods )
{
  Console.WriteLine(info.Name);
  ParameterInfo[] pars = info.GetParameters();
  foreach( ParameterInfo par in pars )
  {
     Console.WriteLine( par.Name + ” : ” + par.ParameterType + ” – ” );
  }
}

which produces this:

TestMethod
par : System.String –
TestMethod
par : System.String –
GetType
ToString
Equals
obj : System.Object –
GetHashCode

To me, this really looks like a method re-definition and no error. on the other hand, I”m positive that the guys that have designed the compiler are really good (a lot better than me ) and that”s why i think I”m still missing something here. If i discover what,I”ll put it here. If you know why this happens,please end with my misery and add a comment to the post 🙂

 [Update: I think I”ve understood why this happens. It seems like the C# generics specification only requires the method”s signature to be unique prior to the class” instantiation. If this is true, then the previous example makes sense nad works as it should. If I”m wrong, please correct me. thanks]