重构方法参数验证代码到合同 - 报表问题的反转

时间:2011-09-12 02:17:37

标签: c# .net c#-4.0 code-contracts

旧验证代码通常检查布尔条件,如果为真,则抛出异常。

相反Contract.Requires(...)则相反(通过检查我们需要否定旧条件)。

我正在重新编写旧代码,有时会看到一些相当高级的布尔语句,反转它们并不容易,只是做Contract.Requires(!(*old statements*))看起来很糟糕而且很混乱。

如果它有类似Contract.RequiresNot()的重构,那么这里就会更清晰明了。

我们也无法添加静态扩展方法。如果有人遇到这个问题并找到了一些好的解决方案,我希望听到它。

2 个答案:

答案 0 :(得分:1)

您可以尝试保留原有的旧版验证,并在验证后立即添加Contract.EndContractBlock电话。来自MSDN:

  

大多数代码都以if-then-throw代码的形式包含一些参数验证。在以下情况下,合同工具将这些陈述视为先决条件:

     
      
  • 语句出现在方法中的任何其他语句之前。
  •   
  • 整套此类陈述之后是明确的Contract方法调用,例如调用RequiresEnsuresEnsuresOnThrow或{{3方法。
  •   
     

当if-then-throw语句出现在此表单中时,工具会将它们识别为遗留需求语句。如果没有其他合同遵循if-then-throw序列,则使用EndContractBlock方法结束代码。

if ( x == null ) throw new ...
Contract.EndContractBlock(); // All previous "if" checks are preconditions
     

请注意,前面测试中的条件是否定的前提条件。 (实际的前提条件是x!= null。)否定的前提条件受到高度限制:必须按照前面的例子所示写入;也就是说,它应该不包含else子句,而then子句的主体必须是单个throw语句。 if测试受纯度和可见性规则的约束(参见Contract.EndContractBlock),但throw表达式仅受纯度规则的约束。但是,抛出的异常类型必须与合同发生的方法一样可见。

答案 1 :(得分:1)

您可以将old statements的结果存储到具有正确名称的布尔变量中。这将摆脱一对令人困惑的括号,并用于自我记录您的代码=)

相关问题