开发者

Refactoring method parameter validation code to Contracts - inversion of statements problem

开发者 https://www.devze.com 2023-04-04 08:40 出处:网络
Old validation code is usually checking a boolean condition, and throws an exception if that is true.

Old validation code is usually checking a boolean condition, and throws an exception if that is true.

Instead Contract.Requires(...) does the opposite (to pass the check we need to negate old condition).

I am refatoring old code and sometimes see some fairly advanced boolean statements, inversing them isn't that easy, and just doing Contract.Requires(!(*old statements*)) appears bad and very confusing.

If it had something like Contra开发者_如何转开发ct.RequiresNot() refactoring would be much more clear and straightforward here.

We also cannot add a static extension method. If someone encountered this problem and found some good solution I would like to hear it.


You could try leaving the old legacy validations in place and adding a Contract.EndContractBlock call immediately following the validations. From MSDN:

Most code contains some parameter validation in the form of if-then-throw code. The contract tools recognize these statements as preconditions in the following cases:

  • The statements appear before any other statements in a method.
  • The entire set of such statements is followed by an explicit Contract method call, such as a call to the Requires, Ensures, EnsuresOnThrow, or EndContractBlock method.

When if-then-throw statements appear in this form, the tools recognize them as legacy requires statements. If no other contracts follow the if-then-throw sequence, end the code with the Contract.EndContractBlock method.

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

Note that the condition in the preceding test is a negated precondition. (The actual precondition would be x != null.) A negated precondition is highly restricted: It must be written as shown in the previous example; that is, it should contain no else clauses, and the body of the then clause must be a single throw statement. The if test is subject to both purity and visibility rules (see Usage Guidelines), but the throw expression is subject only to purity rules. However, the type of the exception thrown must be as visible as the method in which the contract occurs.


You could store the result of old statements in to a boolean variable with a proper name. That would get rid of the pair of confusing parenthesis and also serve to self-document your code =)

0

精彩评论

暂无评论...
验证码 换一张
取 消