如何将对象的类型与泛型类型进行比较,与泛型参数无关?

gri*_*yvp 11 c# generics

说明我的问题的最好方法是使用此示例代码:

  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 >() );
    }
  }
Run Code Online (Sandbox Code Playgroud)

以下行不起作用:

else if( typeof( Container<> ) == something.GetType() )
Run Code Online (Sandbox Code Playgroud)

它是一个方法,使之没有明确地改变工作Container<>Container<int>?我想知道对象是'容器'类型,我真的没有兴趣是它Container<int>还是Container<string>.除了几十行反射之外的任何提示?

Meh*_*ari 28

尝试:

typeof(Container<>) == something.GetType().GetGenericTypeDefinition()
Run Code Online (Sandbox Code Playgroud)

请注意,如果实际类型为,则仅返回true Container<T>.它不适用于派生类型.例如,它将返回false以下内容:

class StringContainer : Container<string>
Run Code Online (Sandbox Code Playgroud)

如果你需要让它适用于这种情况,你应该遍历继承层次结构并测试每个基类是否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);
}
Run Code Online (Sandbox Code Playgroud)