Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic type inheritance

public class BaseGenericType<T>
{
}

public class SubGenericType<T>: BaseGenericType<List<T>>
{
}

I have two generic types above, which one inherits from another but is still generic. The strange thing I can't figure out is that typeof(SubGenericType<>).IsSubclassOf(typeof(BaseGenericType<>)) returns false. And typeof(SubGenericType<>).IsSubclassOf(typeof(BaseGenericType<List<>>)) still returns false. I've tried GetGenericTypeDefinition() and MakeGenericType() and GetGenericArguments() to check the inheritance, still not working. But typeof(SubGenericType<int>).IsSubclassOf(typeof(BaseGenericType<List<int>>)) returns true.

What I want is to get all classes by reflection then grab the specific class which inherits from a generic type passed in.

e.g.

(1)List<int> -->

(2)get generic type definition ==> List<T> -->

(3)make generic ==> BaseGenericType<List<T>> -->

(4)find subclass ==> SubGenericType<T>

(5)make generic ==> SubGenericType<int>

In step (4) I find nothing although I actually have that SubGenericType<T>. Why is that?

like image 538
Sean C. Avatar asked Oct 19 '22 08:10

Sean C.


1 Answers

Once I wrote this method to check generic type inheritance:

    static bool IsSubclassOfOpenGeneric(Type generic, Type toCheck)
    {
        while (toCheck != null && toCheck != typeof(object))
        {
            var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
            if (generic == cur)
            {
                return true;
            }
            toCheck = toCheck.BaseType;
        }
        return false;
    }

This returns true:

IsSubclassOfOpenGeneric(typeof(BaseGenericType<>), typeof(SubGenericType<int>))

It doesn't check interfaces though.

By the way, usually if you have relations like this, and you write all the classes yourself, consider using interfaces. It is much easier to handle. You can for instance have a IGenericType interface without generic argument. Sometome you just do not care about the generic type and just want to access members which do not depend on the generic type. Sometimes you want to simply check if it is one of those. And you can use type variance.

like image 174
Stefan Steinegger Avatar answered Nov 15 '22 05:11

Stefan Steinegger