将方法参数验证代码重构为Contracts - 语句反转问题

发布于 2024-12-04 05:24:07 字数 337 浏览 1 评论 0 原文

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

相反,Contract.Requires(...) 执行相反的操作(为了通过检查,我们需要否定旧条件)。

我正在重构旧代码,有时会看到一些相当高级的布尔语句,反转它们并不那么容易,并且仅仅执行 Contract.Requires(!(*old statements*)) 看起来很糟糕并且非常令人困惑。

如果它有类似 Contract.RequiresNot() 的东西,重构在这里会更加清晰和直接。

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

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 Contract.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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一个人的旅程 2024-12-11 05:24:07

您可以尝试保留旧的遗留验证并添加

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

当 if-then-throw 语句以这种形式出现时,工具会将它们识别为旧版 require 语句。如果没有其他合约遵循 if-then- throw 序列,则以 Contract.EndContractBlock 方法。

if ( x == null ) 抛出新...
Contract.EndContractBlock(); // 之前所有的“if”检查都是先决条件

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


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:

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.

沧笙踏歌 2024-12-11 05:24:07

您可以将旧语句的结果存储到具有适当名称的布尔变量中。这将摆脱一对令人困惑的括号,并且还可以自我记录您的代码=)

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 =)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文