我正在查看一些旧代码,我很好奇setter属性中是否包含逻辑,或者是否有更好的编写方法,为什么?谢谢!
string qBankCode;
string qCode;
public string QBankCode
{
get => qBankCode;
set
{
if (value.Length == 0)
throw new ArgumentException("You need to enter the question bank code as it is mandatory.");
if (value.Length > 30)
throw new ArgumentException("Question bank code cannot exceed 30 characters.");
qBankCode = value;
}
}
public string QCode
{
get => qCode;
set
{
if (value.Length == 0)
throw new ArgumentException("You need to enter the question code as it is mandatory.");
if (value.Length > 30)
throw new ArgumentException("Question code cannot exceed 30 characters.");
qCode = value;
}
}
根据Framework Design Guidelines:
Setter可以抛出异常
✓如果属性设置器抛出异常,请保留先前的值。
✓允许以任何顺序设置属性,即使这会导致对象的临时无效状态。
只要它们不依赖于其他属性的状态,例如
public string QCode
{ ... set {...
if (QBankCode.Length ==10 && value.Length % 2 == 0)
throw new exception();...
您的代码示例满足此要求,但您应确保属性具有合理的默认值
✓为所有属性提供合理的默认值,...
我认为在属性设置器中使用逻辑通常不可行,但是您的示例显示validation不仅可行,而且是很好的做法。
或者如果有更好的方法来编写此内容,为什么?
它确实取决于代码的使用方式。
例如,对于MVC或EntityFramework模型,人们可以主张StringLength
和Required
属性。请参阅Adding Validation to the Model (C#)或StringLengthAttribute Class 。
如果确实很重要,则应在多个级别上进行验证(抛出和使用属性)。
[请注意,属性需要框架(MVC,EF等)来强制执行,而throw new ArgumentException
将在所有情况下均可用,这可能是理想的选择。
请注意,例外在库的构建版本中不可见,如果您的模型以二进制形式分发,则通过其他方式传达验证规则非常重要。
[请注意,虽然验证异常可以确保在必须部署多种语言或无需部署新代码的情况下允许更改消息的情况下阻止不良值,但是您必须想出其他方法来处理验证失败。
Microsoft的Property Design .NET指南中的状态
✓允许以任何顺序设置属性,即使这会导致对象的临时无效状态。
通常,两个或多个属性与某个属性的某个点相互关联,在该点上,鉴于同一对象上其他属性的值可能无效。在这种情况下,由无效状态引起的异常应推迟到对象实际一起使用相互关联的属性为止。
我强烈不同意这种设计,但与往常一样,在某些情况下它有意义。
我发现将对象保持在有效状态的系统更易于使用,我总是首先鼓励不可变的类设计。