工厂来创建泛型类
本文关键字:泛型类 创建 工厂 | 更新日期: 2023-09-27 18:27:10
我有一个名为Validator:的抽象类
public abstract class Validator<T> where T : IValidatable
{
public abstract bool Validate(T input);
}
我有一些具体的实现。一个是AccountValidator:
public class AccountCreateValidator : Validator<IAccount>
{
public override bool Validate(IAccount input)
{
//some validation
}
}
另一个是LoginValidator:
public class LoginValidator : Validator<IAccount>
{
public override bool Validate(IAccount input)
{
//some different validation
}
}
我现在想创建一个工厂来返回验证器实现的一个实例。类似于:
public static class ValidatorFactory
{
public static Validator GetValidator(ValidationType validationType)
{
switch (validationType)
{
case ValidationType.AccountCreate:
return new AccountCreateValidator();
}
}
}
我想把它叫做
Validator myValidator = ValidatorFactory.GetValidator(ValidationType.AccountCreate);
然而,它不喜欢返回新的AccountCreateValidator()行,也不喜欢我将myValidator声明为Validator而不是Validator<SomeType>
。如有任何帮助,我们将不胜感激。
您似乎正在使用工厂将枚举参数转换为具体的验证实现。但我可以想象,尽管调用者不知道或不关心验证器的具体类型,但它可能知道它希望验证的类型。这意味着将GetValidator方法作为一种通用方法是合理的:
public static Validator<TypeToValidate> GetValidator<TypeToValidate>(ValidationType validationType) where TypeToValidate : IValidatable
然后调用代码如下所示:Validator<IAccount> validator = ValidatorFactory.GetValidator<IAccount>(ValidationType.AccountCreate
)
如果你想像你所说的那样使用它,而不指定泛型参数,那么你可以声明一个非泛型接口,并让Validator抽象类实现它。未经测试,但大致如下:
public interface IValidator
{
bool Validate(object input);
}
public abstract class Validator<T> : IValidator where T : IValidatable
{
public abstract bool Validate(T input);
public bool Validate (object input)
{
return Validate ((T) input);
}
}
public static class ValidatorFactory
{
public static IValidator GetValidator(ValidationType validationType)
{
switch (validationType)
{
case ValidationType.AccountCreate:
return new AccountCreateValidator();
}
}
}
然后这个代码:
IValidator myValidator = ValidatorFactory.GetValidator(ValidationType.AccountCreate);
应该工作正常。
通常我会有一个接受Type
作为参数的工厂,这样工厂就会创建一个唯一的派生类型。但是,因为您有多个验证器,它们接受相同类型的对象进行验证(在本例中为IAccount
),我认为您必须向工厂提供通用参数,以及创建什么类型的验证器,如下所示:
public static class ValidatorFactory
{
public static Validator<T> GetValidator<T>(ValidationType validationType)
where T : IValidatable
{
switch (validationType)
{
case ValidationType.AccountCreate:
return new AccountCreateValidator() as Validator<T>;
// etc...
}
}
}
我试过打电话:
var value = ValidatorFactory.GetValidator<IAccount>(ValidationType.AccountCreate)
并且这现在将CCD_ 5转换为正确的CCD_。
这并不理想,因为您现在需要知道您想要什么验证器以及它接受什么输入,但如果由于我添加了显式强制转换(例如ValidatorFactory.GetValidator<IUser>(ValidationType.AccountCreate)
应该失败)而传递了错误的输入类型,那么您应该会收到编译错误。
EDIT:因为有评论说这不会编译,所以我编辑了上面的代码片段,将其转换为new AccountCreateValidator() as Validator<T>
。我以为它可以选任何一种方式,但显然不是(但不确定为什么)。我已经在LINQPad中验证了这一点,我可以从验证器中得到结果。
我还相信,我之前关于如果传入错误的泛型类型,可能会出现编译错误的评论不再适用于使用as
关键字进行强制转换,如果无法执行,则只会返回null
。