Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if type is derived from abstract generic class

I need to get all types that derive from some abstract generic class. I also need to get generic type (like GetGenericArguments() on type that implement generic interface).

This is sample code:

public abstract class AbstractValidator<T>

public class CreateTripValidator : AbstractValidator<CreateTrip>

public class CancelTripValidator : AbstractValidator<CancelTrip>

I want to load all types that derive from AbstractValidator. In this example CreateTripValidator and CancelTripValidator. And I want check type of generic argument for each of them.

I tried in this way but none of them works:

var types = Assembly.GetExecutingAssembly().GetTypes().Where(
                    t => t.IsSubclassOf(typeof(AbstractValidator<>)));

var types = Assembly.GetExecutingAssembly().GetTypes().Where(
                    t => t.IsAssignableFrom(typeof(AbstractValidator<>)));
like image 413
geek Avatar asked Mar 20 '23 00:03

geek


2 Answers

static bool IsValidatorType(Type t)
{
    while(t != null)
    {
        if(t.IsGenericType && t.GetGenericTypeDefinition == typeof(AbstractValidator<>))
        {
            return true;
        }
        t = t.BaseClass;
    }
    return false;
}

var validatorTypes = Assembly.GetExecutingAssembly().GetTypes()
    .Where(IsValidatorType);
like image 63
Lee Avatar answered Mar 23 '23 00:03

Lee


You must to check with your own hands all base types:

private static bool IsSubclassOfRawGeneric(Type baseType, Type derivedType) {
    while (derivedType != null && derivedType != typeof(object)) {
        var currentType = derivedType.IsGenericType ? derivedType.GetGenericTypeDefinition() : derivedType;
        if (baseType == currentType) {
            return true;
        }

        derivedType = derivedType.BaseType;
    }
    return false;
}

And then you can use it like this:

    var validatorType = typeof(AbstractValidator<>);
    var subTypes = validatorType.Assembly
        .GetTypes()
        .Where(t => IsSubclassOfRawGeneric(validatorType, t));

Ideone: R7Q88Z

like image 25
Viktor Lova Avatar answered Mar 22 '23 23:03

Viktor Lova