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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10718364/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 14:58:01  来源:igfitidea点击:

Check if 'T' inherits or implements a class/interface

c#generics

提问by user1229895

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
}

采纳答案by nikeee

There is a Method called Type.IsAssignableFrom().

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

To check if Tinherits/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())

回答by Sachin Kainth

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

回答by snajahi

If you want to check during compilation: Error if if Tdoes NOTimplement 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.

我希望这有帮助。

回答by Chalky

I believe syntax is: typeof(Employee).IsAssignableFrom(typeof(T));

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

回答by Luke

The correct syntax is

正确的语法是

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

Documentation

文档

Return Value:trueif cand the current Typerepresent the same type, or if the current Typeis in the inheritance hierarchy of c, or if the current Typeis an interfacethat cimplements, or if cis a generic type parameter and the current Typerepresents one of the constraints of c, or if crepresents a value type and the current Typerepresents Nullable<c>(Nullable(Of c)in Visual Basic). falseif none of these conditions are true, or if cis null.

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

source

来源

Explanation

解释

If Employee IsAssignableFrom Tthen Tinherits from Employee.

如果Employee IsAssignableFrom T然后T继承自Employee.

The usage

用法

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

returns trueonlywhen either

true在以下任一情况下返回

  1. Tand Employeerepresent the same type; or,
  2. Employeeinherits from T.
  1. TEmployee代表同一类型;或者,
  2. Employee继承自T.

This may be intended usage in somecase, but for the original question (and the more common usage), to determine when Tinherits or implements some class/interface, use:

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

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

回答by drzaus

What everyone really means is:

每个人真正的意思是:

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

because you can literally assign froman instance of a DerivedTypeto an instance of a BaseType:

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

False

baseclass->child1

True

child2->baseclass

False

baseclass->child2

True

nobase->baseclass

False

baseclass->nobase

False

基类->基类

真的

child1->基类

错误的

基类->child1

真的

child2->基类

错误的

基类->child2

真的

nobase->基类

错误的

基类-> nobase

错误的

and

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

回答by Jed

Although IsAssignableFrom is the best way as others have stated, if you only need to check if a class inherits from another, typeof(T).BaseType == typeof(SomeClass)does the job too.

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

回答by Suncat2000

Alternate ways to tell if an object oinherits a class or implements an interface is to use the isand asoperators.

判断对象是否o继承类或实现接口的替代方法是使用isas运算符。

If you want to only know if an object inherits a class or implements an interface, the isoperator 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 asoperator 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.

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