Tricky Generics: "New" Keyword and Generics
Trying to decide how to write some unit test helper classes, I ran into an interesting question. What happens when you use the new keyword along with .NET generics? The example below shows my dilemma:
1: [TestMethod]
2: public void DoBase()
3: { 4: DoT<Base>(new Base());
5: }
6:
7: [TestMethod]
8: public void DoDerived()
9: { 10: DoT<Derived>(new Derived());
11: }
12:
13: public void DoT<T>(T item)
14: where T : Base
15: { 16: item.Blah();
17: }
18:
19: public class Base
20: { 21: public Base()
22: { 23: }
24:
25: public void Blah()
26: { 27: Console.WriteLine("Hello"); 28: }
29: }
30:
31: public class Derived : Base
32: { 33: public new void Blah()
34: { 35: Console.WriteLine("Bye"); 36: }
37: }
The question is what happens when you call DoDerived()? Because the class is typed as T (which in this case is the Derived class), you would expect "Bye" to be written to the console. How would that work though, since the compiler has no concept of Derived.Blah, and therefore cannot generate the IL to access it at compile time of the generic?
Sure enough, "Hello" will be written from Base.Blah, as if we were cast to Base at the time of invocation.