C# 检查';T';继承或实现类/接口

C# 检查';T';继承或实现类/接口,c#,generics,C#,Generics,有没有办法测试T是否继承/实现了类/接口 private void MyGenericClass<T> () { if(T ... inherits or implements some class/interface } private void MyGenericClass() { if(T…)继承或实现某个类/接口 } 您可以对类使用约束 MyClass<T> where T : Employee MyClass,其中T:Employee 看一看有一个

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

private void MyGenericClass<T> ()
{
    if(T ... inherits or implements some class/interface
}
private void MyGenericClass()
{
if(T…)继承或实现某个类/接口
}

您可以对类使用约束

MyClass<T> where T : Employee
MyClass,其中T:Employee
看一看

有一个方法叫做

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

typeof(Employee).IsAssignableFrom(typeof(T));
如果您的目标是.NET Core,则该方法已移动到TypeInfo:

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

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

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

public void MyRestrictedMethod<T>() where T : MyInterface1, MyInterface2, MySuperClass
{
    //Code of my method here, clean without any check for type constraints.
}
public void MyRestrictedMethod(),其中T:MyInterface1、MyInterface2、MySuperClass
{
//这里是我方法的代码,没有任何类型约束检查。
}

我希望这能有所帮助。

我相信语法是:
typeof(Employee)。IsAssignableFrom(typeof(T));
正确的语法是

typeof(Employee).IsAssignableFrom(typeof(T))
文档 返回值:
true
如果
c
和当前的
Type
表示相同的类型,或者如果当前的
Type
c
的继承层次结构中,或者如果当前的
Type
c
实现的
接口,或者如果
c
是一个泛型类型pe参数和当前
Type
表示
c
的约束之一,或者如果
c
表示值类型,当前
Type
表示
null
null(在Visual Basic中为c)
)如果这些条件均为
true
,或者
c
null
,则为
false

解释 如果
Employee是可从T
签名的,则
T
继承自
Employee

用法

typeof(T).IsAssignableFrom(typeof(Employee)) 
返回
true
仅当

  • T
    Employee
    代表同一类型;或
  • Employee
    继承自
    T
  • 在某些情况下,这可能是预期用途,但对于原始问题(以及更常见的用途),要确定
    T
    何时继承或实现某些
    /
    接口
    ,请使用:

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

    每个人真正的意思是:

    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
    
    什么时候


    还有一些具体的例子,如果你很难把你的头绕在它周围:

    (通过LinqPad,从而实现
    水平运行
    转储

    void Main()
    {
    // http://stackoverflow.com/questions/10718364/check-if-t-inherits-or-implements-a-class-interface
    var b1=新的BaseClass1();
    var c1=新的ChildClass1();
    var c2=新的子类2();
    var nb=新的nobase();
    Util.HorizontalRun(
    “基类->基类,基类->基类,基类->基类,基类->基类,基类->基类,基类->基类,基类->基类,基类->基类”,
    b1.IsAssignableFrom(typeof(BaseClass1)),
    c1.IsAssignableFrom(typeof(BaseClass1)),
    b1.IsAssignableFrom(typeof(ChildClass1)),
    c2.IsAssignableFrom(typeof(BaseClass1)),
    b1.IsAssignableFrom(typeof(ChildClass2)),
    注:IsAssignableFrom(typeof(BaseClass1)),
    b1.IsAssignableFrom(类型(nobase))
    ).Dump(“结果”);
    var results=新列表();
    串试验;
    test=“c1=b1”;
    试一试{
    c1=(儿童1类)b1;
    结果。添加(测试);
    }catch{results.Add(“FAIL:+test);}
    test=“b1=c1”;
    试一试{
    b1=c1;
    结果。添加(测试);
    }catch{results.Add(“FAIL:+test);}
    test=“c2=b1”;
    试一试{
    c2=(儿童2级)b1;
    结果。添加(测试);
    }catch{results.Add(“FAIL:+test);}
    test=“b1=c2”;
    试一试{
    b1=c2;
    结果。添加(测试);
    }catch{results.Add(“FAIL:+test);}
    结果:Dump();
    }
    //在此处定义其他方法和类
    公共静态类exts{
    公共静态bool IsAssignableFrom(此T实体,类型为baseType){
    返回类型为(T).IsAssignableFrom(baseType);
    }
    }
    类BaseClass1{
    公共int id;
    }
    类ChildClass1:BaseClass1{
    公共字符串名称;
    }
    儿童班2:儿童班1{
    公共字符串描述;
    }
    诺贝尔班{
    公共int id;
    公共字符串名称;
    公共字符串描述;
    }
    
    结果 基类->基类

    真的

    child1->baseclass

    假的

    基类->child1

    真的

    child2->基类

    假的

    基类->child2

    真的

    nobase->baseclass

    假的

    基类->nobase

    假的

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

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

    判断对象
    o
    是否继承类或实现接口的另一种方法是使用
    is
    作为
    操作符

    如果只想知道对象是否继承类或实现接口,
    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.
    
    如果你
    bool isCompatibleType = (o is BaseType || o is IInterface);
    
    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.