旧验证代码通常检查布尔条件,如果为真,则抛出异常。
相反Contract.Requires(...)
则相反(通过检查我们需要否定旧条件)。
我正在重新编写旧代码,有时会看到一些相当高级的布尔语句,反转它们并不容易,只是做Contract.Requires(!(*old statements*))
看起来很糟糕而且很混乱。
如果它有类似Contract.RequiresNot()
的重构,那么这里就会更清晰明了。
我们也无法添加静态扩展方法。如果有人遇到这个问题并找到了一些好的解决方案,我希望听到它。
答案 0 :(得分:1)
您可以尝试保留原有的旧版验证,并在验证后立即添加Contract.EndContractBlock电话。来自MSDN:
大多数代码都以if-then-throw代码的形式包含一些参数验证。在以下情况下,合同工具将这些陈述视为先决条件:
- 语句出现在方法中的任何其他语句之前。
- 整套此类陈述之后是明确的Contract方法调用,例如调用Requires,Ensures,EnsuresOnThrow或{{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
的结果存储到具有正确名称的布尔变量中。这将摆脱一对令人困惑的括号,并用于自我记录您的代码=)