Check if a class is derived from a generic class

2018-12-31 15:24发布

I have a generic class in my project with derived classes.

public class GenericClass<T> : GenericInterface<T>
{
}

public class Test : GenericClass<SomeType>
{
}

Is there any way to find out if a Type object is derived from GenericClass?

t.IsSubclassOf(typeof(GenericClass<>))

does not work.

16条回答
与君花间醉酒
2楼-- · 2018-12-31 16:00

@EnocNRoll - Ananda Gopal 's answer is interesting, but in case an instance is not instantiated beforehand or you want to check with a generic type definition, I'd suggest this method:

public static bool TypeIs(this Type x, Type d) {
    if(null==d) {
        return false;
    }

    for(var c = x; null!=c; c=c.BaseType) {
        var a = c.GetInterfaces();

        for(var i = a.Length; i-->=0;) {
            var t = i<0 ? c : a[i];

            if(t==d||t.IsGenericType&&t.GetGenericTypeDefinition()==d) {
                return true;
            }
        }
    }

    return false;
}

and use it like:

var b = typeof(char[]).TypeIs(typeof(IList<>)); // true

There are four conditional cases when both t(to be tested) and d are generic types and two cases are covered by t==d which are (1)neither t nor d is a generic definition or (2) both of them are generic definitions. The rest cases are one of them is a generic definition, only when d is already a generic definition we have the chance to say a t is a d but not vice versa.

It should work with arbitrary classes or interfaces you want to test, and returns what as if you test an instance of that type with the is operator.

查看更多
与风俱净
3楼-- · 2018-12-31 16:02

You can try this extension

    public static bool IsSubClassOfGenericClass(this Type type, Type genericClass,Type t)
    {
        return type.IsSubclassOf(genericClass.MakeGenericType(new[] { t }));
    }
查看更多
裙下三千臣
4楼-- · 2018-12-31 16:04

This can all be done easily with linq. This will find any types that are a subclass of generic base class GenericBaseType.

    IEnumerable<Type> allTypes = Assembly.GetExecutingAssembly().GetTypes();

    IEnumerable<Type> mySubclasses = allTypes.Where(t => t.BaseType != null 
                                                            && t.BaseType.IsGenericType
                                                            && t.BaseType.GetGenericTypeDefinition() == typeof(GenericBaseType<,>));
查看更多
怪性笑人.
5楼-- · 2018-12-31 16:09

Here's a little method I created for checking that a object is derived from a specific type. Works great for me!

internal static bool IsDerivativeOf(this Type t, Type typeToCompare)
{
    if (t == null) throw new NullReferenceException();
    if (t.BaseType == null) return false;

    if (t.BaseType == typeToCompare) return true;
    else return t.BaseType.IsDerivativeOf(typeToCompare);
}
查看更多
登录 后发表回答