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

后端 未结 8 1783
名媛妹妹
名媛妹妹 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: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 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(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

提交回复
热议问题