我想知道在 getters 和 setters 或代码中的其他地方进行验证是否是一个好主意。
对于优化和加速代码,这可能会让您感到惊讶,我认为您不应该在getter和setter中进行验证,而是在代码中您更新您的文件或数据库。我错了吗?
答案 0 :(得分:14)
好吧,其中一个原因是为什么类通常包含带有公共getter / setter的私有成员,这正是因为他们可以验证数据。
如果你的数字可以介于1和100之间,我肯定会在setter中放入一些验证它的东西,然后可能抛出一个被代码捕获的异常。原因很简单:如果你不在setter中这样做,你必须记住每次设置时1到100的限制,这会导致重复的代码,或者当你忘记它时,它会导致无效的状态。 / p>
至于表现,我在这里与Knuth:
“我们应该忘记效率低下,大约97%的时间说:过早的优化是所有邪恶的根源。”
答案 1 :(得分:4)
@Terrapin,重新:
如果你拥有的只是一堆[简单 public set / get]属性......他们 也许是字段
与字段相比,属性具有其他优势。它们是一个更明确的契约,它们是序列化的,它们可以在以后调试,它们是通过继承扩展的好地方。笨拙的语法是偶然的复杂性 - 例如.net 3.5克服了这一点。
一种常见的(也是有缺陷的)做法是从公共字段开始,然后在“根据需要”的基础上将它们转换为属性。这违反了与消费你的班级的任何人的合同,所以最好从属性开始。
答案 2 :(得分:3)
从拥有最易维护的代码的角度来看,我认为你应该在属性的setter中尽可能多地进行验证。这样您就不会缓存或以其他方式处理无效数据。
毕竟,这就是属性的意思。如果您拥有的是一堆属性,如...
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
......他们可能也是字段
答案 3 :(得分:3)
取决于。
通常,代码应该快速失败。如果值可以由代码中的多个点设置,并且只在检索到值后验证,则错误似乎出现在执行更新的代码中。如果setter验证输入,您就知道正在尝试设置无效值的代码。
答案 4 :(得分:1)
验证方法中应与getter或setter分开捕获验证。这样,如果验证需要跨多个组件重用,则可以使用。
当调用setter时,应该使用这样的验证服务来清理对象的输入。这样,您就知道存储在对象中的所有信息始终有效。
您不需要对getter进行任何类型的验证,因为对象的信息已被信任有效。
在数据库更新之前不要保存验证! 快速失败会更好。
答案 5 :(得分:1)
你可能想看看Eric Evans的Domain Driven Design。 DDD有这个规范的概念:
...显式谓词式VALUE 用于特殊目的的对象。一个 SPECIFICATION是一个谓词 确定一个对象是做还是做 不满足某些标准。
我认为快速失败是一回事,另一个是保持验证逻辑的地方。域是保持逻辑的正确位置,我认为Domain对象上的规范对象或验证方法将是一个好地方。
答案 6 :(得分:1)
我喜欢实现IDataErrorInfo并将我的验证逻辑放在其Error和this [columnName]属性中。这样,如果您想以编程方式检查是否存在错误,您只需在代码中测试这些属性中的任何一个,或者您可以将验证交给Web窗体,Windows窗体或WPF中的数据绑定。
WPF的“ValidatesOnDataError”绑定属性使这一点变得特别容易。
答案 7 :(得分:1)
我尝试永远不会让我的对象进入无效状态,因此setter肯定会进行验证以及任何改变状态的方法。这样,我就不必担心我正在处理的对象是无效的。如果您将方法保持为验证边界,那么您永远不必担心验证框架和遍布整个地方的IsValid()方法调用。