繁体   English   中英

工厂创建泛型类

[英]Factory to create generic classes

我有一个名为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)

现在返回一个AccountCreateValidator Validator<IAccount>转换为正确的Validator<IAccount>类型。

它并不完全理想,因为您现在需要知道您想要的验证器以及它接受的输入,但是如果由于我添加的显式ValidatorFactory.GetValidator<IUser>(ValidationType.AccountCreate)传递了错误的输入类型,您应该希望得到编译错误,例如ValidatorFactory.GetValidator<IUser>(ValidationType.AccountCreate)应该失败。

编辑:因为评论说这不会编译,我编辑了上面的代码片段作为new AccountCreateValidator() as Validator<T>进行演员。 我认为它可以是任何一种方式,但显然不是(不确定为什么)。 我已经在LINQPad中验证了这个功能,我可以从验证器获得结果。

我也相信我之前关于可能会出现编译错误的评论,如果传入错误的泛型类型不再表示使用as关键字进行投射,如果无法执行,则返回null

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM