C#在setter方法上添加验证

Mar*_*hin 8 c# getter setter properties

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

public String firstName { get; set; }
public String lastName { get; set; }
public String organization { get; set; }
Run Code Online (Sandbox Code Playgroud)

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

jas*_*son 26

如果要验证何时设置属性,则需要使用非自动属性(即手动定义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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,你可以说:

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

这是我更喜欢的方法:

  1. A Customer不应该负责验证自己的数据,这是另一项责任,因此应该生活在其他地方.
  2. 不同的情况为同一域对象调用不同的验证逻辑.

  • 我不同意,即使您的验证失败,您的客户数据也无效.如果搞乱外部验证,阻止它将垃圾写入数据库是什么? (5认同)
  • @Blindy 客户不应该负责写入数据库。那将是客户不应该承担的另一项责任。 (3认同)
  • @Blindy:你的持久层应该与验证失败时不持久的验证器相连。 (2认同)

Str*_*ior 9

你现在所谓的"自动属性",只执行一个简单的"获取/设置".为了自定义getor 的行为set,您需要将属性转换为字段支持的属性:

private string _firstName;
public string FirstName 
{ 
    get {return _firstName;} 
    set 
    {
       Validate(value); _firstName = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我按照接受的C#命名最佳实践更改Stringstring属性名称并将其大写.