tags:

views:

93

answers:

1

Best way to illustrate my question is with this example code:

  class Item {}
  class Container< T > {}
  class Program
  {
    static void DoSomething( object something )
    {
      if( typeof( Item ) == something.GetType() )
      {
        System.Console.WriteLine( "Item" );
      }
      else if( typeof( Container<> ) == something.GetType() )
      {
        System.Console.WriteLine( "Container<>" );
      }
    }

    static void Main( string[] args )
    {
      DoSomething( new Item() );
      DoSomething( new Container< int >() );
    }
  }

The following line will not work:

else if( typeof( Container<> ) == something.GetType() )

Is it a way to make it work without explicitly changing Container<> into Container<int>? I want to know that object is of 'Container' type and I really has no interest is it Container<int> or Container<string>. Any hints other than dozens lines of reflection?

+10  A: 

Try:

typeof(Container<>) == something.GetType().GetGenericTypeDefinition()

Note that this will only return true if the actual type is Container<T>. It doesn't work for derived types. For instance, it'll return false for the following:

class StringContainer : Container<string>

If you need to make it work for this case, you should traverse the inheritance hierarchy and test each base class for being Container<T>:

static bool IsGenericTypeOf(Type genericType, Type someType)
{   
  if (someType.IsGenericType 
          && genericType == someType.GetGenericTypeDefinition()) return true;

  return someType.BaseType != null 
          && IsGenericTypeOf(genericType, someType.BaseType);
}
Mehrdad Afshari
Thanks, it's more than enough for my purpose.
Eye of Hell
Love the way our parallel edits went along the same lines :)
Jon Skeet
@Jon: Indeed! * *
Mehrdad Afshari