代码合同 - 没有正确警告只读成员?

时间:2012-06-09 15:08:08

标签: c# code-contracts

鉴于这门课程,我不确定为什么我会收到确认未经证实的结果!= null警告。

public class MyClass {
  private readonly string _value;

  public MyClass(string value) {
    Contract.Requires(value != null);  
    _value = value;
  }

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

我可以通过添加一个_value!= null的Invariant来消除警告,但感觉就像我不应该这样。这只是分析的限制吗?

编辑:在问题中添加更多内容,因为我认为我的问题遗漏了。

public class Test {
    private string _value = "";

    public string Value {
        get {
            Contract.Ensures(Contract.Result<string>() != null);
            return _value;
        }
        set {
            Contract.Requires<ArgumentNullException>(value != null);
            _value = value;
        }
    }
}

CC分析似乎对这门课非常满意;在ctor中分配了一个非空值,并且可以证明更改Requires因此_value的setter Ensures非空值。

2 个答案:

答案 0 :(得分:1)

您的构造函数不保证_value将为非null。它将_value设置为value,这是非空的,但这是一个实现细节,而不是合同的一部分。即使它是合同的一部分,也是不够的,因为当你添加另一个没有做同样承诺的构造函数时,所有前置条件和后置条件应该保持同样有效。

您应该添加_value != null的不变量。为什么你觉得不应该这样?

修改:作为替代方案,您可以尝试添加Value != null(在MyClass之外也很有用)的不变量,并生成Value的属性getter确保Contract.Result<string>() == _value(仅仅是为了证明不变量),但我不确定它是否会起作用。

答案 1 :(得分:1)

当问到这个问题时,我不确定该选项是否可用,但我今天遇到了类似的问题,并发现通过启用“代码合同”选项“推断读取不变量”,警告就消失了。