【问题标题】:Pass Class Property as Generic Type将类属性作为通用类型传递
【发布时间】:2015-07-17 02:19:35
【问题描述】:

我正在尝试为FluentValidation 实现一个基类,它将快速为类构建一个验证器。我的基类函数尝试将类的属性作为通用类型参数以应用规则。但正如您将在代码中看到的那样,它在语法上(除其他外)并不完全正确。

用代码解释起来可能更容易:

public class BaseValidator<T>  : AbstractValidator<T>
{
    public void ruleForText<U>(string msg)
    {
        RuleFor(obj => obj.U).NotEmpty().WithMessage(msg);
        RuleFor(obj => obj.U).Length(1, 100).WithMessage(msg);
        RuleFor(obj => obj.U).Matches("[A-Z]*").WithMessage(msg);
    }

    public void ruleForEmail<U>(string msg)
    {
        RuleFor(obj => obj.U).NotEmpty().WithMessage(msg);
        RuleFor(obj => obj.U).EmailAddress().WithMessage(msg);
    }
}

public class Member {
    public string Name { get; set; }
    public string Email { get; set; }
}

public class Post{
    public string Title { get; set; }
}

public class MemberValidator :BaseValidator<Member>
{
    public MemberValidator()
    {
        // Not valid syntax to pass name or even Member.Name
        // How can I pass Member.Name as the generic type?
        ruleForText<Name>();
        ruleForEmail<Email>();
    }
}

public class PostValidator :BaseValidator<Post>
{
    public MemberValidator()
    {
        ruleForText<Title>();
    }
}

【问题讨论】:

  • 泛型作用于类型,而不是成员本身。我可以看到你在做什么,但泛型不是做到这一点的方法,只是没有办法将泛型硬塞进你的目标中。
  • RuleFor 是如何定义的? ruleForEmail/Test 中的 obj 是什么?关于您的代码有很多问题......我认为您希望将您的 ruleForText 声明为采用 Func&lt;U&gt; 并将 () =&gt; Name 传递给它。
  • 为什么不能只传递属性值来验证它? RuleFor(string valueToValidate, string msg);

标签: c# generics fluentvalidation


【解决方案1】:

这可能是您正在寻找的。您需要传入一个函数参数为字符串的表达式。

public class BaseValidator<T> : AbstractValidator<T>
{
    public void RuleForText(Expression<Func<T, string>> expression, string msg)
    {
        RuleFor(expression).NotEmpty().WithMessage(msg);
        RuleFor(expression).Length(1, 100).WithMessage(msg);
        RuleFor(expression).Matches("[A-Z]*").WithMessage(msg);
    }

    public void RuleForEmail(Expression<Func<T, string>> expression, string msg)
    {
        RuleFor(expression).NotEmpty().WithMessage(msg);
        RuleFor(expression).EmailAddress().WithMessage(msg);
    }
}

public class MemberValidator : BaseValidator<Member>
{
    public MemberValidator()
    {
        RuleForText(member => member.Name, "My Message");
        RuleForEmail(member => member.Email, "My Message");
    }
}

public class Member
{
    public string Name { get; set; }
    public string Email { get; set; }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-24
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多