我通过Contract.Requires()
Contract.Ensures()
和CultureInfo.GetCultureInfo(string)
注释现有代码来学习如何通过合同进行设计。
在修复了我实际引起的警告后,我开始注意到框架中的许多方法都无法确保其发布条件。这让我很担心,因为静态检查员现在对我可能违反我的先决条件的行为给予了误报。
未实现代码合同的方法示例:
null
在任何情况下都不会返回Contracts.Requires(culture != null)
。不过,我无法使用它:
var culture = CultureInfo.GetCultureInfo("en");
Contract.Assume(culture != null);
MyPreconditionalMethod(culture);
如果我这样做,静态检查器会给我这个:
CodeContracts:需要未经证实:culture!= null
那么,我该怎么办?忽略警告并写一个带有文档链接的注释?或者有没有办法证明其他人写的方法的后置条件?
修改
做出假设似乎会使分析器闭嘴,但直到下次我编写相同的代码行。
[ContractClassFor()]
我查看了{{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
警告。