在代码合同中指定参数“可以为null或不为null”?

时间:2015-01-06 16:08:48

标签: c# null code-contracts

我可能会遗漏某些东西,或者我可能会向CC询问我不应该做的事情,但是 -

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

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

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

通过上述内容,ccchecker请让我知道冗余:

  

CodeContracts:建议要求:此前提条件是多余的:请考虑将其删除。


更新: Matt Burland总结了意图,如果改变了回应,

  

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

3 个答案:

答案 0 :(得分:2)

如果要求价值可以是任何值,那么就不要求任何东西,而不是明确地添加价值可以是任何值的要求。

答案 1 :(得分:1)

代码合约不需要被告知参数可以是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>

答案 2 :(得分:0)

可以使用代码合同完成,但不能使用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!";
}