106

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

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

8 回答 8

155

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

检查是否T继承/实现Employee

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

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

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

请注意,如果您想约束您的类型T以实现某个接口或从某个类继承,您应该选择@snajahi 的答案,该答案使用编译时检查,通常类似于解决此问题的更好方法。

于 2012-05-23T10:50:55.760 回答
36

您可以在类上使用约束。

MyClass<T> where T : Employee

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

于 2012-05-23T10:46:35.120 回答
19

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

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

我希望这会有所帮助。

于 2014-03-27T12:31:21.757 回答
13

正确的语法是

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

文档

返回值: true如果c和 currentType表示相同的类型,或者如果 currentType在 的继承层次结构中c,或者如果 currentTypeinterface实现的c,或者 ifc是泛型类型参数并且 currentType表示的约束之一c,或者ifc表示值类型,而 currentType表示Nullable<c>Nullable(Of c)在 Visual Basic 中)。false如果这些条件都不是true,或者如果cnull

来源

解释

如果Employee IsAssignableFrom TthenT继承自Employee.

用途

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

true 当任一时返回

  1. TEmployee代表同一类型;或者,
  2. Employee继承自T

在某些情况下,这可能是预期用途,但对于原始问题(以及更常见的用法),要确定何时T继承或实现某些class/ interface,请使用:

typeof(Employee).IsAssignableFrom(typeof(T))
于 2014-07-29T14:49:48.043 回答
11

每个人真正的意思是:

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

因为您可以从字面上将 a 的实例分配给aDerivedType的实例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,因此HorizontalRunand Dump

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;
}

结果

基类->基类

真的

child1->基类

错误的

基类->child1

真的

child2->基类

错误的

基类->child2

真的

nobase->基类

错误的

基类-> nobase

错误的

  • 失败:c1 = b1
  • b1 = c1
  • 失败:c2 = b1
  • b1 = c2
于 2015-11-25T17:46:33.963 回答
2

我相信语法是:typeof(Employee).IsAssignableFrom(typeof(T));

于 2014-06-17T20:29:51.083 回答
0

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

于 2017-05-24T07:28:03.180 回答
0

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

如果你只想知道一个对象是继承了一个类还是实现了一个接口,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.

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

于 2019-04-25T21:18:11.897 回答