我需要获得从一些抽象泛型类派生的所有类型。我还需要获得泛型类型(如实现通用接口的类型上的GetGenericArguments())。
这是示例代码:
public abstract class AbstractValidator<T>
public class CreateTripValidator : AbstractValidator<CreateTrip>
public class CancelTripValidator : AbstractValidator<CancelTrip>
我想加载从AbstractValidator派生的所有类型。在此示例中,CreateTripValidator和CancelTripValidator。我想为每个人检查通用参数的类型。
我试过这种方式,但没有一个有效:
var types = Assembly.GetExecutingAssembly().GetTypes().Where(
t => t.IsSubclassOf(typeof(AbstractValidator<>)));
var types = Assembly.GetExecutingAssembly().GetTypes().Where(
t => t.IsAssignableFrom(typeof(AbstractValidator<>)));
答案 0 :(得分:3)
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);
答案 1 :(得分:1)
您无法从未构造的泛型类型中寻找派生。您必须在Type.GetGenericTypeDefinition()上明确呼叫BaseType,以检查它是否等于typeof(AbstractValidator<>)
。
请注意,如果您使用标记界面(例如IAbstractValidator&#39;这是非通用的,可能会暴露非通用的包装方法供消费者使用,而这些方法并不知道确切的类型。如果你使用它,你可以使用IsAssignableFrom,尽管你必须小心不要让它倒退。您希望typeof(IAbstractValidator).IsAssignableFrom(type)
获得正确的检查。这种特殊的方法很容易翻转,因为它看起来类似于if (x is type)
。
答案 2 :(得分:1)
您必须亲自检查所有基本类型:
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;
}
然后你可以像这样使用它:
var validatorType = typeof(AbstractValidator<>);
var subTypes = validatorType.Assembly
.GetTypes()
.Where(t => IsSubclassOfRawGeneric(validatorType, t));
Ideone:R7Q88Z