如何测试类的实例是否是特定的泛型类型?

时间:2010-11-05 04:05:14

标签: c# .net generics reflection

假设我有一个简单的泛型类,如下所示

public class MyGenericClass<t>
{
   public T {get;set;}
}

如何测试类的实例是否为MyGenericClass?例如,我想做这样的事情:

MyGenericClass x = new MyGenericClass<string>();
bool a = x is MyGenericClass;
bool b = x.GetType() == typeof(MyGenericClass);

但我不能只引用MyGenericClass。 Visual Studio总是要我写MyGenericClass<something>

4 个答案:

答案 0 :(得分:2)

要测试您的实例是否为MyGenericClass<T>类型,您可以编写类似的内容。

MyGenericClass<string> myClass = new MyGenericClass<string>();
bool b = myClass.GetType().GetGenericTypeDefinition() == typeof(MyGenericClass<>);

如果您希望能够将对象声明为MyGenericClass而不是MyGenericClass<string>,则需要MyGenericClass的非泛型基础作为继承树的一部分。但此时,您只能在基础上引用属性/方法,除非您稍后转换为派生泛型类型。直接声明通用实例时,不能省略type参数。*

*当然,您可以选择使用类型推断并编写

var myClass = new MyGenericClass<string>();

编辑:Adam Robinson在评论中提出了一个很好的观点,说你有class Foo : MyGenericClass<string>。上面的测试代码不会将Foo的实例标识为MyGenericClass<>,但您仍然可以编写代码来测试它。

Func<object, bool> isMyGenericClassInstance = obj =>
    {
        if (obj == null)
            return false; // otherwise will get NullReferenceException

        Type t = obj.GetType().BaseType;
        if (t != null)
        {
            if (t.IsGenericType)
                return t.GetGenericTypeDefinition() == typeof(MyGenericClass<>);
        }

        return false;
    };

bool willBeTrue = isMyGenericClassInstance(new Foo());
bool willBeFalse = isMyGenericClassInstance("foo");

答案 1 :(得分:0)

List<int> testInt = new List<int>();
List<string> testString = new List<string>();

if (testInt .GetType().Equals(testString.GetType()))
 Console.WriteLine("Y");
else Console.WriteLine("N");

它的'N'

testInt.GetType().Equals(typeof(List<int>))
is true

但如果你只想要班级名称

testInt.GetType().FullName

答案 2 :(得分:0)

如果需要,您可以使泛型类实现一些任意(可能是空的)接口。测试某个对象是否属于通用泛型类只是测试它是否实现了该接口。无需明确使用反射。

答案 3 :(得分:0)

我使用以下内容(因为我发现所有建议都不适用于我。

  public static bool IsGenericTypeOf(Type vtype, Type target) {
     return
           vtype.IsGenericType
        && target.ContainsGenericParameters
        && vtype.Name == target.Name
        && vtype.Assembly == target.Assembly
        && vtype.Module == target.Module
        ;
  }