[英]Constrain generic type on a method to be any class that is derived from any variant form of an abstract generic base class
[英]Check if type is derived from abstract generic class
我需要获得从一些抽象泛型类派生的所有类型。 我还需要获得泛型类型(如实现通用接口的类型上的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<>)));
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);
您必须亲自检查所有基本类型:
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
您无法从未构造的泛型类型中查找派生。 您必须在BaseType上显式调用Type.GetGenericTypeDefinition()以检查它是否等于typeof(AbstractValidator<>)
。
请注意,如果您使用非常规的“IAbstractValidator”等标记接口,这种事情通常会更容易,可能会暴露非通用的包装器方法,供不知道确切类型的使用者使用。 如果你使用它,你可以使用IsAssignableFrom,尽管你必须小心不要让它倒退。 你需要typeof(IAbstractValidator).IsAssignableFrom(type)
来获得正确的检查。 这个特殊的方法很容易翻转,因为它似乎类似于if (x is type)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.