简体   繁体   English

检查“T”是否继承或实现了一个类/接口

[英]Check if 'T' inherits or implements a class/interface

Is there a way to test if T inherits/implements a class/interface?有没有办法测试 T 是否继承/实现了一个类/接口?

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

There is a Method called Type.IsAssignableFrom() .有一个名为Type.IsAssignableFrom()的方法。

To check if T inherits/implements Employee :要检查T继承/实现Employee

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

If you are targeting .NET Core, the method has moved to TypeInfo:如果您的目标是 .NET Core,则该方法已移至 TypeInfo:

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

Note that if you want to constrain your type T to implement some interface or inherit from some class, you should go for @snajahi's answer, which uses compile-time checks for that and genereally resembles a better approach to this problem.请注意,如果您想限制您的类型T以实现某个接口或从某个类继承,您应该选择@snajahi 的答案,它使用编译时检查,并且通常类似于解决此问题的更好方法。

You can use constraints on the class.您可以在类上使用约束。

MyClass<T> where T : Employee

Take a look at http://msdn.microsoft.com/en-us/library/d5x73970.aspx看看http://msdn.microsoft.com/en-us/library/d5x73970.aspx

If you want to check during compilation: Error if if T does NOT implement the desired interface/class, you can use the following constraint如果您想在编译期间检查:如果T没有实现所需的接口/类,则错误,您可以使用以下约束

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

I hope that helps.我希望这有帮助。

The correct syntax is正确的语法是

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

Documentation文档

Return Value: true if c and the current Type represent the same type, or if the current Type is in the inheritance hierarchy of c , or if the current Type is an interface that c implements, or if c is a generic type parameter and the current Type represents one of the constraints of c , or if c represents a value type and the current Type represents Nullable<c> ( Nullable(Of c) in Visual Basic).返回值: true如果c和当前Type表示相同的类型,或者如果当前Type是在继承层次结构c ,或者如果当前Type是一个interfacec器具,或者如果c是一个通用的类型参数和current Type表示c的约束之一,或者如果c表示值类型并且当前Type表示Nullable<c> (在 Visual Basic 中为Nullable(Of c) )。 false if none of these conditions are true , or if c is null . false如果这些条件都不是true ,或者如果cnull

source 来源

Explanation解释

If Employee IsAssignableFrom T then T inherits from Employee .如果Employee IsAssignableFrom TT继承自Employee

The usage用法

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

returns true only when either在以下任一情况下返回true

  1. T and Employee represent the same type; TEmployee代表同一种类型; or,要么,
  2. Employee inherits from T . EmployeeT继承。

This may be intended usage in some case, but for the original question (and the more common usage), to determine when T inherits or implements some class / interface , use:某些情况下,这可能是预期用途,但对于原始问题(以及更常见的用法),要确定T何时继承或实现某些class / interface ,请使用:

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

What everyone really means is:每个人真正的意思是:

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

because you can literally assign from an instance of a DerivedType to an instance of a BaseType :因为您可以从字面上DerivedType的实例分配给BaseType的实例:

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

when什么时候

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

And some concrete examples if you're having trouble wrapping your head around it:如果您无法理解它,还有一些具体的例子:

(via LinqPad, hence the HorizontalRun and Dump ) (通过 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;
}

Results结果

baseclass->baseclass基类->基类

True真的

child1->baseclass child1->基类

False错误的

baseclass->child1基类->child1

True真的

child2->baseclass child2->基类

False错误的

baseclass->child2基类->child2

True真的

nobase->baseclass nobase->基类

False错误的

baseclass->nobase基类-> nobase

False错误的

and

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

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

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

Alternate ways to tell if an object o inherits a class or implements an interface is to use the is and as operators.判断对象o继承类或实现接口的替代方法是使用isas运算符。

If you want to only know if an object inherits a class or implements an interface, the is operator will return a boolean result:如果你只想知道一个对象是继承了一个类还是实现了一个接口, is操作符将返回一个布尔结果:

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

If you want to use the inherited class or implemented interface after your test, the as operator will perform a safe cast, returning a reference to the inherited class or the implemented interface if compatible or null if not compatible:如果您想在测试后使用继承的类或实现的接口, 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.

If you have only the type T , then use @nikeee's answer.如果您只有T类型,请使用@nikeee 的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在运行时创建类型,继承抽象类并实现接口 - Create type at runtime that inherits an abstract class and implements an interface 如何检查类是否在NRefactory中实现接口方法 - How to check if a class implements interface methods in NRefactory 检查类的泛型参数是否实现接口 - Check if generic parameter of a class implements an interface 如果一个类继承自己实现IDisposable的接口,那么该类是否也应该实现IDisposable? - If a class inherits from an interface that itself implements IDisposable should that class also implement IDisposable or not? VB.NET 类继承一个基类并实现一个接口问题(在 C# 中工作) - VB.NET class inherits a base class and implements an interface issue (works in C#) 从实现接口的抽象类继承的类,并进行反射性加载 - Class which inherits from abstract class which implements interface, and loading this reflectively 我怎样才能拥有一个实现接口并继承自抽象 class 的 class? (C# .NET 3.5) - How can I have a class that implements an interface and inherits from an abstract class? (C# .NET 3.5) 不是每个继承接口的类都应该实现所有接口成员吗? - Shouldn't every class that inherits an interface implement all interface members? 检查T是否实现接口,并在填充接口属性后返回T - Check if T implements an interface and return T after populating interface properties 如何在 map 继承抽象 class 并在 nHibernate 中同时实现接口的类? - How to map a calss that inherits an asbtract class and implements an interface at the same time in nHibernate?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM