如何识别对象是否为基本通用类型?

AJ *_*son 2 c# generics inheritance

我上课了.

DataMapper<TDalType, TFieldType> : DataMapperBase
Run Code Online (Sandbox Code Playgroud)

对于某个特定的实体,我有一个

ObjectADataMapper<TFieldType> : DataMapper<ObjectADal, TFieldType>
Run Code Online (Sandbox Code Playgroud)

然后我有一个DataMapperBase的实例,需要确定它是否是一个ObjectADataMapper版本的实体(具有任何TFieldType值).

sma*_*man 6

您可以通过查看对象的类型是否为通用以及相应的通用模板是否是您要查找的通用模板来检查此问题.例如:

var type = obj.GetType();
bool isObjectADataMapper = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObjectADataMapper<>);
Run Code Online (Sandbox Code Playgroud)

或者,以可重用的方式

  bool IsInstanceOfGenericTypeClosingTemplate(object obj, Type genericTypeDefinition){ 
      if(obj == null) throw new ArgumentNullException("obj");
      if(genericTypeDefinition== null) throw new ArgumentNullException("genericTypeDefinition");
      if(!genericTypeDefinition.IsGenericTypeDefinition) throw new ArgumentException("Must be a generic type definition.", "genericTypeDefinition");
      Type type = obj.GetType(); 
      return type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition;
  }
Run Code Online (Sandbox Code Playgroud)

您甚至可以更进一步,看看该类型是否来自相关的泛型类型定义.例如,考虑您有:

  public class StringDataMapper : ObjectADataMapper<string>
  { 
     // .... whatever
  }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我提供的方法将失败.所以你必须做类似的事情

  bool IsInstanceOfGenericTypeClosingTemplateOrSubclassThereof(object obj, Type genericTypeDefinition){ 
      if(obj == null) throw new ArgumentNullException("obj");
      if(genericTypeDefinition== null) throw new ArgumentNullException("genericTypeDefinition");
      if(!genericTypeDefinition.IsGenericTypeDefinition) throw new ArgumentException("Must be a generic type definition.", "genericTypeDefinition");

      Type type = obj.GetType();
      while ( type != typeof(object) )
      {
         if(type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition) 
         {
            return true;
         }
         type = type.BaseType;
      } 
      return false;
  }
Run Code Online (Sandbox Code Playgroud)