Friday, December 21, 2012

where T : Whatever

More fun from "C# 4.0 in a Nutshell": In the second line below, the ourSound string will end up set to "PuRRRRRRRRRRRRR" and the way in which it happens is pretty interesting...

Purrer<Tiger> purrer = new Purrer<Tiger>();
string ourSound = purrer.Purr();

 
 

OK, this is our Purrer class...

using System;
using System.Reflection;
public class Purrer<T> where T : Cat
{
   public Purrer()
   {
   }
   
   public string Purr()
   {
      Type type = typeof (T);
      var infos = type.GetMethods();
      MethodInfo info = infos[0];
      Cat cat = (Cat)type.GetConstructor(new Type[] { }).Invoke(new object[] { });
      return "Pu" + info.Invoke((object)cat, new object[] { }).ToString();
   }
}


 
 

Above, please note:

  1. T cannot just be anything as is the norm. A contract restrains T to Cat.
  2. On the second to last line the constructor of T is invoked to make a T-shaped Cat.
  3. On the last line the first method in the new T-shaped Cat is invoked with no parameters and an assumed return value is cast to a string.
  4. That is all of the magic there is!

 
 

The Cat object looks like so...

public class Cat
{
   public Cat()
   {
   }
   
   public virtual string Growl()
   {
      return "rrrrrr";
   }
}

 
 

The Tiger child of Cat overrides the Growl method to make the growl "louder" for a Tiger. The magic of this pattern happens in overriding. You may guarantee that FooProcessor will understand the methods of Foo while also being able to accomodate the variations of Foo's children.

public class Tiger : Cat
{
   public Tiger()
   {
   }
   
   public override string Growl()
   {
      return "RRRRRRRRRRRRR";
   }
}

 
 

 
 

Man, this posting is so nice and fluffy and cat-related. What's wrong with me?

No comments:

Post a Comment