使用在其return语句中创建特定新对象的方法时,"Invariant unproven"

Dan*_*rth 18 c# code-contracts

以下简单代码将通过Code Contracts的静态检查器产生"不变的未经证实"警告,尽管_foo无法做到null.警告是针对return内部声明的UncalledMethod.

public class Node
{
    public Node(string s1, string s2, string s3, string s4, object o,
                string s5)
    {
    }
}

public class Bar
{
    private readonly string _foo;

    public Bar()
    {
        _foo = "foo";
    }

    private object UncalledMethod()
    {
        return new Node(string.Empty, string.Empty, string.Empty, string.Empty,
                        GetNode(), string.Empty);
    }

    private Node GetNode()
    {
        return null;
    }

    public string Foo
    {
        get
        {
            Contract.Ensures(Contract.Result<string>() != null);
            return _foo;
        }
    }

    [ContractInvariantMethod]
    private void Invariants()
    {
        Contract.Invariant(_foo != null);
    }
}
Run Code Online (Sandbox Code Playgroud)

除了事实之外,警告只是无效,它只会在某些特定情况下发生.更改以下任何内容都会使警告消失:

  1. 内联GetNode所以return语句如下所示:

    return new Node(string.Empty, string.Empty, string.Empty, string.Empty, null,
                    string.Empty);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从构造函数中删除任何参数s1到s5 Node.
  3. 改变任何参数s1的类型从构造至s5 Nodeobject.
  4. 使用临时变量得到以下结果GetNode:

        var node = GetNode();
        return new Node(string.Empty, string.Empty, string.Empty, string.Empty,
                        node, string.Empty);
    
    Run Code Online (Sandbox Code Playgroud)
  5. 更改构造函数的参数顺序Node.
  6. 在项目设置的代码协定设置窗格中选中"显示假设"选项.

我错过了一些明显的东西,或者这只是静态检查器中的一个错误?


我的设置:

我的输出:

C:\{path}\Program.cs(20,9): message : CodeContracts: Suggested ensures: Contract.Ensures(this._foo != null);
C:\{path}\Program.cs(41,17): message : CodeContracts: Suggested ensures: Contract.Ensures(Contract.Result<System.String>() == this._foo);
C:\{path}\Program.cs(33,13): message : CodeContracts: Suggested ensures: Contract.Ensures(Contract.Result<ConsoleApplication3.Program+Node>() == null);
C:\{path}\Program.cs(27,13): message : CodeContracts: Suggested ensures: Contract.Ensures(Contract.Result<System.Object>() != null);
C:\{path}\Program.cs(55,13): message : CodeContracts: Suggested ensures: Contract.Ensures(Contract.ForAll(0, args.Length, __k__ => args[__k__] != 0));
CodeContracts: ConsoleApplication3: Validated:  92,3%
CodeContracts: ConsoleApplication3: Contract density: 1,81
CodeContracts: ConsoleApplication3: Total methods analyzed 8
CodeContracts: ConsoleApplication3: Methods with 0 warnings 7
CodeContracts: ConsoleApplication3: Total method analysis read from the cache 8
CodeContracts: ConsoleApplication3: Total time 2,522sec. 315ms/method
CodeContracts: ConsoleApplication3: Retained 0 preconditions after filtering
CodeContracts: ConsoleApplication3: Inferred 0 object invariants
CodeContracts: ConsoleApplication3: Retained 0 object invariants after filtering
CodeContracts: ConsoleApplication3: Detected 0 code fixes
CodeContracts: ConsoleApplication3: Proof obligations with a code fix: 0
C:\{path}\Program.cs(27,13): warning : CodeContracts: invariant unproven: _foo != null
C:\{path}\Program.cs(49,13): warning :   + location related to previous warning
C:\windows\system32\ConsoleApplication3.exe(1,1): message : CodeContracts: Checked 13 assertions: 12 correct 1 unknown
CodeContracts: ConsoleApplication3: 
CodeContracts: ConsoleApplication3: Background contract analysis done.
Run Code Online (Sandbox Code Playgroud)

Dan*_*rth 1

最新版本不再有这个问题。