1

顺便说一句,我一直在查看FluentValidation哪个是一个不错的验证库,但我注意到它们传入LambdaExpression而不是对象属性,我想了解这种用法​​的优势:

using FluentValidation;

public class CustomerValidator: AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Company).NotNull();
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);

bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;

正如您所看到RuleFor(customer => customer.Surname).NotEmpty();的那样, RuleFor(customer.Surname).NotEmpty();还不够干净吗?

4

2 回答 2

6

相反,RuleFor(customer.Surname).NotEmpty();还不够干净吗?

不,因为在您打电话时RuleFor,您没有客户 - 因此您无法访问他们的姓氏。

与委托的情况一样,您正在传递要在以后执行的代码。该表达式customer.Surname是一个将在现有变量的上下文中立即计算的表达式。customer

现在,如果我们有神话般的infoof运算符,我们可以在不创建委托的情况下做到这一点。我们可能会写出类似的东西:

RuleFor(infoof(Customer.Surname)).NotEmpty()

这将是可爱的。该RuleFor方法将获取该属性引用并稍后针对给定客户对其进行评估。精彩的。

不幸的是,我们没有那个运营商——所以表达“当你有客户时,抓住Surname财产”这个想法的最简单方法是使用委托。它也非常灵活,因为它(几乎)可以处理您想要执行的任何代码。

于 2012-08-23T17:51:51.387 回答
1

如果您要传递customer.SurName,您将指向SurName特定customer实例的属性值。使用 lambda 函数允许验证逻辑在调用验证逻辑时获取客户对象,然后检索该客户SurName的属性。

于 2012-08-23T17:53:52.060 回答