Code Contracts警告可能会失败'假设'电话

时间:2011-03-05 00:08:38

标签: c# code-contracts

在我的一个班级中,我有一个ExpandoObject类型的私有字段。该字段在constructior(this.expected = new ExpandoObject())中初始化,因此我相信它永远不会是null

因此,在本课程的其中一个方法中,我可以安全地添加

Contract.Assumes(this.expected != null)

在使用this.expected进行任何操作之前,所以Code Contracts不必担心对null对象的可能调用。但是,我没有警告可能的方法调用空引用,而是收到警告

  

对方法'Assume'的动态调度调用可能在运行时失败,因为一个或多个适用的重载是条件方法

方法签名和前几行代码如下所示:

protected void Expect(object values)
{
    Contract.Requires<ArgumentNullException>(values != null);

    Contract.Assume(this.expected != null);
    var exp = (ICollection<KeyValuePair<string, object>>)this.expected;

在第三行,我收到

的警告
  

CodeContracts:可能在空引用'OddEnds.Testing.TestBase.o_ SiteContainer0上调用方法。&lt;&gt; p _Site3.Target'

其中我假设空引用的奇数签名是因为exp是一个动态对象。

我如何解决这些问题?

2 个答案:

答案 0 :(得分:4)

我认为解决问题的最佳方法是声明expected永远不会作为类的不变量为空:

class TheClass {

    ExpandoObject expected;

    ...

    [ContractInvariantMethod]
    void Invariants()
    {
        Contract.Invariant(this.expected != null);
    }

    ...

}

执行此操作时,静态检查器将检查构造函数末尾的expected是否为空,然后它将知道expected在任何其他方法的开头都不为null

答案 1 :(得分:0)

我认为下面的代码更改将使编译器保持高兴(如果您确定无论如何都在使用expand,那么为什么还要使用expandoobject ...)

ICollection<KeyValuePair<string, object>> col = this.expected as ICollection<KeyValuePair<string, object>>;
Contract.Assume(col != null);