[英]Static contract unproven, because reference is passed to another method (that only reads)
其他人在合同上遇到麻烦。 我有以下几点:
public void doSomeThing(Stack stack)
{
Contract.Requires(stack != null);
stack.Push("$");
Contract.Assert(stack.Count > 0); //redundant check
_Look(stack);
Contract.Assert(stack.Count > 0); //this contract fails static analysis, because analyser does not know that _Look does not write to stack.
stack.Pop();
}
private void _Look(Stack stack)
{
//do nothing
}
第二个断言未得到证实,因为对_Look的调用可能(但不会)更改堆栈的内容。 有没有办法说_Look不会更改堆栈? 还是有其他方法可以使它正常工作?
请注意,这些合同是动态通过的,只是不能静态证明第二个合同。
因此,似乎您正在使用Contracts来验证_Look方法正确工作。 我相信这样做的正确方法是将之前和之后的验证转移到_Look方法中。 与之共处时,除非您不信任无法控制的堆栈,否则不需要您的第一个断言。 鉴于此,我将执行以下操作:
public void doSomeThing(Stack stack)
{
Contract.Requires(stack != null);
stack.Push("$");
_Look(stack);
stack.Pop();
}
private void _Look(Stack stack)
{
Contract.Requires(stack != null);
Contract.Requires(stack.Count > 0);
//do something here
Contract.Assert(stack.Count > 0);
}
合同旨在进行前后验证,而不是代码中间的断言。
由于Code Contracts对_Look
方法的功能_Look
,因此无法知道Count
将保持不变。 您需要明确地告诉它:
private void _Look(Stack stack)
{
Contract.Ensures(stack.Count == Contract.OldValue(stack.Count));
//do nothing
}
此答案基于阅读Craig Wilson的答案的想法。
public void doSomeThing(Stack stack)
{
Contract.Requires(stack != null);
stack.Push("$");
Contract.Assert(stack.Count > 0); //redundant check
_Look(stack);
Contract.Assert(stack.Count > 0); //this contract fails static analysis, because analyser does not know that _Look does not write to stack.
stack.Pop();
}
private void _Look(Stack stack)
{
Contract.Ensures(stack.Count == Contract.OldValue(stack.Count));
}
我不知道这是怎么回事。 第二个断言应该通过。 除非您没有弹出任何东西。 它应该留在那里。 这里唯一的事情就是push,pop和assert。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.