在C#中,我正在编写一个使用setter方法检查其属性值的类:
private int _grade
public int Grade {
get { return _grade;}
set { if (value >= this.lowerLimit) _grade = value; }
}
如果某个值被拒绝,我想向应用程序发出信号。我曾考虑使用setGrade函数进行重构,返回bool(接受/拒绝),但是执行someInstance.Grade ++和someInstance.Grade * = 2的能力很重要。简单的函数incrementGrade和divideGrade将使代码变得混乱,并且肯定会有一些我忘记实现的函数(耦合太多)。
我目前的解决方案是在设置之后检查someInstance.Grade的值,以确保它已被设置。但在我看来,这只是将混乱从类转移到应用程序。实际上,应用程序有责任确保正确设置值。
那些经验丰富的人如何处理这个问题?谢谢!
答案 0 :(得分:7)
设定有意义的价值确实是来电者的责任
通常,当值错误时,将ArgumentOutOfRangeException
抛出到setter中是公认的做法。如果调用者期望可能错误的值(例如用户输入),则可以catch
正确的异常。
private int _grade
public int Grade {
get { return _grade;}
set {
if (value < lowerLimit) {
throw new ArgumentOutOfRangeException("value",
string.Format("Grade must be higher than or equal to {0}.", lowerLimit)
);
}
_grade = value; // will not happen if the exception was thrown
}
}
如果您不想要ArgumentNullException
值null
,则ArgumentException
如果您的参数拒绝原因与这两种情况不同,则为{{1}}。
更多 hip 方法是将代码合约用作suggested by Jean-Bernard 但是,此功能仍然有点新,并且在.NET项目中没有广泛使用。
代码合同添加静态分析,以便您在编译阶段发现这样的错误
不过,他们会still throw ArgumentException
s in runtime。
答案 1 :(得分:2)
您可以使用Code Contracts
以下是另一个有更多资源的问题的答案:link
答案 2 :(得分:1)
大多数情况下,我默默地将value
调整为在值范围内,或者根据情况抛出异常。
另一种选择:您可以制作您班级客户可以订阅的活动PropertyValueRejected
:
public class PropertyValueRejectedEventArgs {
public string PropertyName { get; set; }
public object RejectedValue { get; set; }
}
public class MyClass {
public event EventHandler<PropertyValueRejectedEventArgs> PropertyRejected;
private int _grade = -1;
public int Grade {
get { return _grade; }
set {
if (value >= this.lowerLimit) {
_grade = value;
}
else if (PropertyRejected != null) {
PropertyRejected(
this,
new PropertyValueRejectedEventArgs {
PropertyName = "Grade",
RejectedValue = value
}
);
}
}
}
}