我与一位同事讨论了使用代码合同来执行先决条件检查。
假设我们有以下代码:
namespace Project
{
using System;
using System.Diagnostics.Contracts;
public class Thing
{
public string Foo { get; set; }
public int Bar { get; set; }
}
public class ThingsManipulator
{
public void AddThing(Thing thing)
{
Contract.Requires<ArgumentNullException>(thing != null);
// Do something
}
}
}
如果在// Do something
我正在访问thing.Foo
和thing.Bar
做的事情中,我是否也应该通过代码合同来验证它们?
public void AddThing(Thing thing)
{
Contract.Requires<ArgumentNullException>(thing != null);
Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(thing.Foo));
Contract.Requires<ArgumentException>(thing.Bar > 0);
// Do something
}
我的同事说,应该只检查整个参数(即我们应该只放置第一个合同),我认为方法应该检查它们使用的内容,无论它是整个参数还是它的一个属性(即我们应该全部三个合同)。
请注意,我确实理解并同意,如果参数的属性应始终满足要求,则该要求应放在对象的不变检查中。
我指的是通常有效但对特定方法无效的值(例如,在上面的示例中,thing.Bar
可能很高兴持有负值,但AddThing
不喜欢它们)。
我的同事说,在这些情况下,方法签名应该明确它正在使用的所有项目而不是单个对象(例如AddThing(string thingFoo, int thingBar)
),并对它们运行检查。
所以:
- 我们应该验证方法使用什么还是只验证整个参数并“分解”参数?
- 是否有技术原因(无论“它”是什么意思)还是偏好问题?
我无法在手册中找到有关此的指南,也许我错过了什么?