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

use*_*895 88 c# generics

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

private void MyGenericClass<T> ()
{
    if(T ... inherits or implements some class/interface
}
Run Code Online (Sandbox Code Playgroud)

nik*_*eee 123

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

检查是否T继承/实现Employee:

typeof(Employee).IsAssignableFrom(typeof(T));
Run Code Online (Sandbox Code Playgroud)

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

typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).Ge??tTypeInfo())
Run Code Online (Sandbox Code Playgroud)

  • 语法不正确,请参阅下面的答案. (2认同)
  • 虽然这几乎可以工作,但是有一个问题,如果`T`被约束到其他类型`Tother`,那么当执行时,`typeof(T)`实际上将评估为`typeof(TOther)`而不是什么类型`T `你实际上已经通过了,在那种情况下,`typeof(SomeInterface).IsAssignableFrom(typeof(T))`将失败(假设`TOther`也没有实现`SomeInterface`),即使你的具体类型确实实现了`SomeInterface `. (2认同)

Sac*_*nth 30

您可以在类上使用约束.

MyClass<T> where T : Employee
Run Code Online (Sandbox Code Playgroud)

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


sna*_*ahi 12

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

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

我希望有所帮助.


Luk*_*uke 11

正确的语法是

typeof(Employee).IsAssignableFrom(typeof(T))
Run Code Online (Sandbox Code Playgroud)

文档

返回值: true如果c与当前Type表示相同的类型,或者如果当前Type是在继承层次结构c,或者如果当前Typeinterfacec实现,或者如果c是一个通用的类型参数和当前Type表示的约束之一c,或if c表示值类型,当前Type表示Nullable<c>(Nullable(Of c)在Visual Basic中).false如果这些条件都不是true,或者如果cnull.

资源

说明

如果Employee IsAssignableFrom T那么T继承自Employee.

用法

typeof(T).IsAssignableFrom(typeof(Employee)) 
Run Code Online (Sandbox Code Playgroud)

true 在任何一个时返回

  1. TEmployee代表相同的类型; 要么,
  2. Employee继承自T.

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

typeof(Employee).IsAssignableFrom(typeof(T))
Run Code Online (Sandbox Code Playgroud)


drz*_*aus 8

每个人的真正含义是:

typeof(BaseType).IsAssignableFrom(typeof(DerivedType)) // => true
Run Code Online (Sandbox Code Playgroud)

因为你可以一个实例分配DerivedType到一个实例BaseType:

DerivedType childInstance = new DerivedType();
BaseType parentInstance = childInstance; // okay, assigning base from derived
childInstance = (DerivedType) parentInstance; // not okay, assigning derived from base
Run Code Online (Sandbox Code Playgroud)

什么时候

public class BaseType {}
public class DerivedType : BaseType {}
Run Code Online (Sandbox Code Playgroud)

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

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

结果

baseclass->基类

真正

child1->基类

baseclass-> child1

真正

child2->基类

baseclass->的child2

真正

nobase->基类

baseclass-> nobase将

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