我想知道在我的方法中是否有一种不那么详细的输入验证方法。例如,我通常写这样的东西:
public string SomeFunction(string param1, int param2)
{
if(string.IsNullOrEmpty(param1)){
throw new ArgumentException("bla", "param1");
}
if(param2 < 0 || param2 > 100 || param2 == 53)
{
throw new ArgumentOutOfRangeException("eek", "param2");
}
}
现在,我想知道是否有办法设置参数约束并让编译器已经为我处理了这些?我相信这被称为“契约”,我记得看到Spec#应该这样做,但这似乎是一个实验研究项目。
所以我想知道:对于.net 3.5 SP1和理想情况下.net 3.0的输入参数,有没有什么可以给出一个干净的约束条件(至少是像string.IsNullOrEmpty那样经常重复的那些)?
答案 0 :(得分:6)
答案 1 :(得分:2)
您可以引入CheckParameter方法,这样您的原始方法中只有一行代码。
这样的事情:
public string SomeFunction(string param1, int param2)
{
CheckParameterNotNull(param1);
CheckParameterRange(param2, 0, 100, 53);
...
}
当然,您需要一些智能的CheckParameter方法来适应您的所有情况。
答案 2 :(得分:2)
可以在此处找到C#的一个实现:http://www.codeproject.com/KB/cs/designbycontract.aspx
答案 3 :(得分:1)
考虑Microsoft Research的“Spec#”:http://research.microsoft.com/SpecSharp/
它扩展了C#以允许您定义合同,并且他们已经投入了大量的工作来将合同纳入BCL和东西。
答案 4 :(得分:0)
您可以按原样保留所有参数检查代码,但随后将实际工作委托给私有函数。私有函数不会进行参数检查,因为它只会被公共网守功能调用。
private string InternalSomeFunction(string param1, int param2)
{
/* implementation goes here */
}
public string SomeFunction(string param1, int param2)
{
if (string.IsNullOrEmpty(param1)) {
throw new ArgumentException("bla", "param1");
}
if (param2 < 0 || param2 > 100 || param2 == 53) {
throw new ArgumentOutOfRangeException("eek", "param2");
}
return InternalSomeFunction(param1, param2);
}
它和原作一样冗长,但至少你的主要功能并不是那些对方法实现并不重要的东西。
另一方面,通过将参数检查代码从实现的其余部分移开,这也消除了检查的一些自我记录方面。例如,当您查看InternalSomeMethod
时,不再提醒param1
将始终是有效的非空字符串,因此您或维护程序员可能会想要添加一个检查对于后来的内部方法。
答案 5 :(得分:0)
在WebForms类型世界之后进行建模,您可以使用一组ErrorProvider控件并将它们附加到您所关注的关键TextBoxes,CheckBoxes等。无论何时用户更改焦点,您都可以在这些字段中启动检查,或者不管您多喜欢这样做。
然后,您可以创建一个名为IsFormValid的方法,该方法将检查所有ErrorProviders,并在所有ErrorProviders签出时返回一个简单的True值。
然后在你所有的主要代码中,你所要做的就是包装你的处理......
if (IsFormValid)
{
// Processing Magic Goes here.
}
这样做的好处是你可能会有不同的“有效”状态,具体取决于特定方法试图完成的内容。确定电话号码字段可能无效并显示一个小红点,但这不应阻止UpdateFirstLastName方法启动。
答案 6 :(得分:0)
与此同时,自提出这个问题以来,代码合约已经发展,看起来像银弹。
当前的CTP是available here(对于.net 3.5),它是.net 4.0的一部分。