20

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?

svick
  • 236,525
  • 50
  • 385
  • 514
grigoryvp
  • 40,413
  • 64
  • 174
  • 277

1 Answers1

44

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
  • 414,610
  • 91
  • 852
  • 789