证明未实现代码合同的代码的发布条件

时间:2014-07-27 22:45:49

标签: c# code-contracts

我通过Contract.Requires() Contract.Ensures()CultureInfo.GetCultureInfo(string) 注释现有代码来学习如何通过合同进行设计。

在修复了我实际引起的警告后,我开始注意到框架中的许多方法都无法确保其发布条件。这让我很担心,因为静态检查员现在对我可能违反我的先决条件的行为给予了误报。

未实现代码合同的方法示例:

null

the documentation所述:

  • 空输入将导致不变的文化对象。
  • 输入错误将导致异常。

在任何情况下都不会返回Contracts.Requires(culture != null) 。不过,我无法使用它:

var culture = CultureInfo.GetCultureInfo("en");

Contract.Assume(culture != null);

MyPreconditionalMethod(culture);

如果我这样做,静态检查器会给我这个:

  

CodeContracts:需要未经证实:culture!= null

那么,我该怎么办?忽略警告并写一个带有文档链接的注释?或者有没有办法证明其他人写的方法的后置条件?

修改

做出假设似乎会使分析器闭嘴,但直到下次我编写相同的代码行。

[ContractClassFor()]

我查看了{{1}}属性,但需要相互握手。 :\

1 个答案:

答案 0 :(得分:2)

您可以尝试Contracts.Requires(culture != null)而不是Contracts.Assume(culture != null)。这为静态分析器提供了一个提示,即在代码执行的那一点,culture不会为空。在对代码进行进一步分析时,静态分析器将使用此假设

<强>更新

所以,如果你有方法,请说:

public int DoSomething(SomeObject o, int i)
{
    Contract.Requires(o != null);
    Contract.Requires(i > 0);
    // You could combine the conditionals in the Requires: o != null && i > 0

    Contract.Ensures(/* some post condition */);

    int returnValue = 0;
    // Do some stuff

    return returnValue;
}

public void SomeMethodThatDoesSomething(int i)
{
    Contract.Requires(i > 0)

    // Do some stuff
}

public void SomeMethodThatCoordinatesActivities()
{
    int result = DoSomething(new SomeObject(), 10);

    Contract.Assume(result > 0);
    SomeMethodThatDoesSomething(result);
}

静态分析器无法证明result中的SomeMethodThatCoordinatesActivities大于0,因此您会收到contract requires unproven: i警告。通过在调用方法中使用Contract.Assume,您可以向静态分析器提示假设,此时调用时result将大于0 <{1}}并且不会发出SomeMethodThatDoesSomething警告。

上面代码中需要注意的一件有趣的事情是,如果我确实在方法unproven上提供了以下帖子条件:

DoSomething

然后我不需要在Contract.Ensures(Contract.Result<int>() > 0); 中进行Contract.Assumes(...)调用,因为我告诉静态分析器,当SomeMethodThatCoordinatesActivities返回时,它的结果将大于DoSomething所以不需要做出任何假设。静态分析器知道这是真的,永远不会给出0警告。