传递Lambda表达式而不是Object的优点

Tar*_*rik 1 c# lambda fluentvalidation

我一直在审查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;
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 6

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

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

与代理通常的情况一样,您将传递代码以便稍后执行.表达式customer.Surname是一个表达式,可以在现有变量的上下文中立即求customer值.

现在,如果我们有神秘的infoof运算符,我们可以在不创建委托的情况下完成.我们可以写下这样的东西:

RuleFor(infoof(Customer.Surname)).NotEmpty()
Run Code Online (Sandbox Code Playgroud)

哪个会很可爱.该RuleFor方法将采用该属性引用,并在以后针对给定客户对其进行评估.精彩.

不幸的是,我们没有那个运营商 - 所以最简单的方式表达"当你有一个客户,掌握Surname财产" 的想法是使用代表.它也非常灵活,因为它可以(几乎)使用您想要执行的任何代码.