Andre de Cavaignac

Let's blog it out...

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.

Comments

Mat Hobbs said:

The key is "where T : Base" - the compiler only knows that item is Base.

This is not related to generics as such, you see the same with an interface or base class when using the 'new' keyword to reintroduce a method.

# November 27, 2007 5:04 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)