检查'T'是不是继承或实现了一个类/接口

Posted

技术标签:

【中文标题】检查\'T\'是不是继承或实现了一个类/接口【英文标题】:Check if 'T' inherits or implements a class/interface检查'T'是否继承或实现了一个类/接口 【发布时间】:2012-05-29 21:47:44 【问题描述】:

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

private void MyGenericClass<T> ()

    if(T ... inherits or implements some class/interface

【问题讨论】:

这似乎有效......如果(typeof(TestClass).IsAssignableFrom(typeof(T))),有人可以证实我的怀疑吗?谢谢! 我绝对肯定这个答案被重复了很多次! Felix K 即使这个答案被重复了很多次,它也帮助了很多人很多次;)......就像我五分钟前:) 【参考方案1】:

有一个方法叫做Type.IsAssignableFrom()。

检查T是否继承/实现Employee

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

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

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

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

【讨论】:

你应该用一个例子来更新你的答案,例如typeof(T).IsAssignableFrom(typeof(IMyInterface)) 未完成 nikeee;旧答案仍然存在。 :) 我花了几秒钟才弄清楚出了什么问题。无论如何,+1,.net 框架的又一个不错的功能。 其实你说的方式就是我前段时间的方式。我纠正了这个。请参阅以前的 cmets。 T inherits U 实际上转换为 typeof(T).IsAssignableFrom(typeof(U)) 虽然这几乎可行,但存在一个问题,如果 T 被限制为其他类型 TOther,那么在执行时,typeof(T) 实际上将评估为 typeof(TOther) 而不是任何类型T 你实际上已经通过了,在这种情况下,typeof(SomeInterface).IsAssignableFrom(typeof(T)) 将失败(假设 TOther 也没有实现 SomeInterface),即使你的具体类型确实实现了 SomeInterface 在 .net core IsAssignableFrom of TypeInfo 类中只接受 TypeInfo 作为它的唯一参数,因此示例应该如下:typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo())【参考方案2】:

您可以对类使用约束。

MyClass<T> where T : Employee

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

【讨论】:

【参考方案3】:

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

public void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass

    //Code of my method here, clean without any check for type constraints.

希望对你有帮助。

【讨论】:

【参考方案4】:

正确的语法是

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

文档

返回值: true 如果c 和当前Type 表示相同类型,或者如果当前Typec 的继承层次结构中,或者如果当前的Typec 实现的interface,或者如果c 是泛型类型参数并且当前Type 表示c 的约束之一,或者如果c 表示一个值类型和当前Type 代表Nullable&lt;c&gt;(在Visual Basic 中为Nullable(Of c))。 false 如果这些条件都不是true,或者如果cnull

source

说明

如果Employee IsAssignableFrom TT 继承自Employee

用法

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

返回true

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

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

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

【讨论】:

【参考方案5】:

每个人真正的意思是:

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://***.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

【讨论】:

【参考方案6】:

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

【讨论】:

这是预期的语法。 +1【参考方案7】:

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

【讨论】:

除非SomeClass 不是直接从BaseClass 派生的,否则该方法有效。【参考方案8】:

判断对象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 的答案。

【讨论】:

以上是关于检查'T'是不是继承或实现了一个类/接口的主要内容,如果未能解决你的问题,请参考以下文章

java 怎么判断一个类是不是继承了某接口

接口

接口是不是可继承接口? 抽象类是不是可实现(implements)接口? 抽象类是不是可继承实体类(concrete class)?

如何在eclipse中看哪个类继承某个接口

哪些类实现或继承了collection接口?

java继承和接口的区别