检查'T'是否继承或实现了类/接口

时间:2012-05-23 10:44:59

标签: c# generics

有没有办法测试T是否继承/实现了一个类/接口?

private void MyGenericClass<T> ()
{
    if(T ... inherits or implements some class/interface
}

8 个答案:

答案 0 :(得分:109)

有一个名为Type.IsAssignableFrom()的方法。

检查T是否继承/实施Employee

typeof(Employee).IsAssignableFrom(typeof(T));

如果您的目标是.NET Core,则该方法已移至TypeInfo:

typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).Ge‌​tTypeInfo())

答案 1 :(得分:29)

您可以在课堂上使用约束。

MyClass<T> where T : Employee

查看http://msdn.microsoft.com/en-us/library/d5x73970.aspx

答案 2 :(得分:12)

如果要在编译期间进行检查:如果T 没有实现所需的接口/类,则会出错,您可以使用以下约束

public void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass
{
    //Code of my method here, clean without any check for type constraints.
}

我希望有所帮助。

答案 3 :(得分:9)

正确的语法是

typeof(Employee).IsAssignableFrom(typeof(T))

文档

  

返回值: true如果c和当前Type代表相同的类型,或者当前Type是否在继承中c的层次结构,或者当前Typeinterface c实现的c,或者Type是泛型类型参数和当前{{1} }}表示c的约束之一,或者c表示值类型,而当前Type表示Nullable<c>(Visual Basic中的Nullable(Of c))。 false如果这些条件都不是true,或者cnull

source

解释

如果Employee IsAssignableFrom T,则T继承自Employee

用法

typeof(T).IsAssignableFrom(typeof(Employee)) 

时,

仅返回true

  1. TEmployee代表相同的类型;或者,
  2. Employee继承自T
  3. 这可能是某些案例中的用途,但对于原始问题(以及更常见的用法),要确定T何时继承或实现某些class / interface,使用:

    typeof(Employee).IsAssignableFrom(typeof(T))
    

答案 4 :(得分:7)

每个人的真正含义是:

typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true

因为您可以分配DerivedType的实例到BaseType的实例:

DerivedType childInstance = new DerivedType();
BaseType parentInstance = childInstance; // okay, assigning base from derived
childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base

public class BaseType {}
public class DerivedType : BaseType {}

还有一些具体的例子,如果你在头上缠绕它时遇到了麻烦:

(通过LinqPad,因此HorizontalRunDump

void Main()
{
    // http://stackoverflow.com/questions/10718364/check-if-t-inherits-or-implements-a-class-interface

    var b1 = new BaseClass1();

    var c1 = new ChildClass1();
    var c2 = new ChildClass2();
    var nb = new nobase();

    Util.HorizontalRun(
        "baseclass->baseclass,child1->baseclass,baseclass->child1,child2->baseclass,baseclass->child2,nobase->baseclass,baseclass->nobase",
        b1.IsAssignableFrom(typeof(BaseClass1)),
        c1.IsAssignableFrom(typeof(BaseClass1)),
        b1.IsAssignableFrom(typeof(ChildClass1)),
        c2.IsAssignableFrom(typeof(BaseClass1)),
        b1.IsAssignableFrom(typeof(ChildClass2)),
        nb.IsAssignableFrom(typeof(BaseClass1)),
        b1.IsAssignableFrom(typeof(nobase))
        ).Dump("Results");

    var results = new List<string>();
    string test;

    test = "c1 = b1";
    try {
        c1 = (ChildClass1) b1;
        results.Add(test);
    } catch { results.Add("FAIL: " + test); }

    test = "b1 = c1";
    try {
        b1 = c1;
        results.Add(test);
    } catch { results.Add("FAIL: " + test); }

    test = "c2 = b1";
    try {
        c2 = (ChildClass2) b1;
        results.Add(test);
    } catch { results.Add("FAIL: " + test); }

    test = "b1 = c2";
    try {
        b1 = c2;
        results.Add(test);
    } catch { results.Add("FAIL: " + test); }

    results.Dump();
}

// Define other methods and classes here
public static class exts {
    public static bool IsAssignableFrom<T>(this T entity, Type baseType) {
        return typeof(T).IsAssignableFrom(baseType);
    }
}


class BaseClass1 {
    public int id;
}

class ChildClass1 : BaseClass1 {
    public string name;
}

class ChildClass2 : ChildClass1 {
    public string descr;
}

class nobase {
    public int id;
    public string name;
    public string descr;
}

结果

  

baseclass-&GT;基类

     

是的

     

child1-&GT;基类

     

错误

     

baseclass-&GT; child1

     

是的

     

child2-&GT;基类

     

错误

     

baseclass-&GT;的child2

     

是的

     

nobase-&GT;基类

     

错误

     

baseclass-&GT; nobase将

     

  
      
  • 失败:c1 = b1
  •   
  • b1 = c1
  •   
  • 失败:c2 = b1
  •   
  • b1 = c2
  •   

答案 5 :(得分:2)

我认为语法是:typeof(Employee).IsAssignableFrom(typeof(T));

答案 6 :(得分:0)

尽管IsAssignableFrom是其他人所说的最佳方式,但如果您只需要检查某个类是否继承自另一个类,typeof(T).BaseType == typeof(SomeClass)也可以完成这项工作。

答案 7 :(得分:0)

判断对象o是继承类还是实现接口的另一种方法是使用isas运算符。

如果只想知道对象是继承一个类还是实现一个接口,则is运算符将返回一个布尔结果:

bool isCompatibleType = (o is BaseType || o is IInterface);

如果要在测试后使用继承的类或实现的接口,则as运算符将执行安全的转换,如果兼容则返回对继承的类或实现的接口的引用;如果不兼容,则返回null:

BaseType b = o as BaseType; // Null if d does not inherit from BaseType.

IInterface i = o as IInterface; // Null if d does not implement IInterface.

如果您只有T类型,请使用@nikeee的答案。