考虑这种不可变类型:
public class Settings
{
public string Path { get; private set; }
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(Path != null);
}
public Settings(string path)
{
Contract.Requires(path != null);
Path = path;
}
}
这里需要注意两点:
- 有一个契约不变量,它确保
Path
财产永远不会null
- 构造函数检查
path
参数值以尊重先前的合同不变量
在这一点上,一个Setting
实例永远不能有一个null
Path
属性。
现在,看看这种类型:
public class Program
{
private readonly string _path;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_path != null);
}
public Program(Settings settings)
{
Contract.Requires(settings != null);
_path = settings.Path;
} // <------ "CodeContracts: invariant unproven: _path != null"
}
基本上,它有自己的合同不变量(_path
现场),在静态检查期间无法满足(参见上面的评论)。这对我来说听起来有点奇怪,因为它很容易证明:
settings
是不可变的settings.Path
不能为空(因为 Settings 有对应的契约不变量)- 所以通过分配
settings.Path
给_path
,_path
不能为空
我在这里错过了什么吗?