C#在setter方法上添加验证

时间:2011-05-25 15:52:04

标签: c# properties setter getter

我有一些我在C#中定义的变量:

public String firstName { get; set; }
public String lastName { get; set; }
public String organization { get; set; }

我想要的是在尝试设置值时为这些方法添加验证。让我们说你要为firstName设置一个值,我应该通过thrue一个正则表达式来设置,否则应该抛出一个异常。是否可以使用这种“短语法”构建,或者我应该选择标准(如JAVA)getter和setter并在那里验证数据?

5 个答案:

答案 0 :(得分:25)

如果要验证何时设置属性,则需要使用非自动属性(即手动定义的getset方法)。

但另一种验证方法是将验证逻辑与域对象分开。

class Customer {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Organization { get; set; }
}

interface IValidator<T> {
    bool Validate(T t);
}

class CustomerValidator : IValidator<Customer> {
    public bool Validate(Customer t) {
        // validation logic
    }
}

然后,你可以说:

Customer customer = // populate customer
var validator = new CustomerValidator();
if(!validator.Validate(customer)) {
    // head splode
}

这是我更喜欢的方法:

  1. Customer不应负责验证自己的数据,即另一个responsibility,因此应该在其他地方生效。
  2. 不同的情况会为同一个域对象调用不同的验证逻辑。

答案 1 :(得分:9)

您现在拥有的内容称为“自动属性”,只执行简单的“获取/设置”。为了自定义getset的行为,您需要将属性转换为字段支持的属性:

private string _firstName;
public string FirstName 
{ 
    get {return _firstName;} 
    set 
    {
       Validate(value); _firstName = value;
    }
}

请注意,我已将String更改为string,并按照已接受的C#命名最佳做法对属性名称进行了大写。

答案 2 :(得分:3)

我根本不会在setter中添加验证。相反,我会创建一个名为validate的函数...这样,所有验证代码都会分散在setters中的一个位置。

答案 3 :(得分:0)

您必须使用完整属性语法。

答案 4 :(得分:0)

应用SRP是最佳实践。在单独的类中设置验证。

您可以使用FluentValidation

       Install-Package FluentValidation

您将通过继承AbstractValidator<Customer>为Customer类定义一组验证规则:

示例:

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

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

要运行验证程序,请实例化验证程序对象并调用Validate方法,并传入该对象进行验证。

   Customer customer = new Customer();
   CustomerValidator validator = new CustomerValidator();

   ValidationResult result = validator.Validate(customer);

 if(! results.IsValid) {
   foreach(var failure in results.Errors) {
       Console.WriteLine("Property " + failure.PropertyName + " failed validation. Error was: " + failure.ErrorMessage);

} }