繁体   English   中英

静态合同未经证明,因为引用被传递给另一种方法(只能读取)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM