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

后端 未结 8 1785
名媛妹妹
名媛妹妹 2020-12-08 04:00

Is there a way to test if T inherits/implements a class/interface?

private void MyGenericClass ()
{
    if(T ... inherits or implements some class/i         


        
相关标签:
8条回答
  • 2020-12-08 04:20

    There is a Method called Type.IsAssignableFrom().

    To check if T inherits/implements Employee:

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

    If you are targeting .NET Core, the method has moved to TypeInfo:

    typeof(Employee).GetTypeInfo().IsAssignableFrom(typeof(T).Ge‌​tTypeInfo())
    
    0 讨论(0)
  • 2020-12-08 04:22

    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 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)

    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

    and

    • FAIL: c1 = b1
    • b1 = c1
    • FAIL: c2 = b1
    • b1 = c2
    0 讨论(0)
提交回复
热议问题