在代码协定中指定参数“可能为空或不为空”

本文关键字:代码 参数 | 更新日期: 2023-09-27 18:36:22

我可能错过了一些东西,或者我可能要求CC提供一些我不应该错过的东西,但是 -

有没有办法指定参数"可能为空,也可能不为空"而不会完全冗余?

例如,想象一下这个人为的例子:

string F(string x)
{
    Contract.Requires(x == null || x != null);
    return x ?? "Hello world!";
}

综上所述,ccchecker善意地让我知道冗余:

代码合约:建议要求:此前提条件是多余的:考虑将其删除。


更新:马特·伯兰德总结了意图,如果这改变了任何回应,

[该] OP 希望能够做的是记下他们没有忘记添加要求......

在代码协定中指定参数“可能为空或不为空”

如果要求值可以是任何东西,那么就不需要任何东西,而不是显式添加值可以是任何东西的要求。

代码协定不需要被告知参数可以null。需要告诉用户可以null参数。为此,您有 XML 文档注释:

/// <param name="x">
/// <para>The string...</para>
/// <para>-or-</para>
/// <para><see langword="null"/> if ...</para>
/// </param>
/// <returns>
/// <para><paramref name="x"/> if it is not <see langword="null"/>.</para>
/// <para>-or-</para>
/// <para>The string <c>Hello World!</c> if <paramref name="x"/> is <see langword="null"/>.</para>
/// </returns>

可以通过代码协定来完成,但不能用Require来完成。对于 require,检查器总是警告它是多余的:即使冗余是"正确"的意图,它也表达不正确。

相反,可以使用Assert,因为它的处理方式略有不同,并且会导致警告。(但是,我找不到记录此警告行为差异的位置。

这告诉检查器,即使它是重言式,条件也应该是真实的静态验证的。生成的运行时工件也略有不同(如果有),但这解决了问题的目标。

string F(string x)
{
    // No Requires as there is no external restriction on x
    // .. but we can still ask the analyzer to play along.
    Contract.Assert(x == null || x != null);
    return x ?? "Hello world!";
}