我已设法将其归结为以下测试用例,但我想知道这是否是 C# 代码合同中静态检查器的限制,还是我缺少的东西。当我尝试使用一种代码来证明合同时,它会抛出一个不变的未经证实的警告,但是(我认为是)一种证明它可以正常工作的等效方法。
最初我认为这可能是因为我没有使用具有 Pure 属性的对象(因此代码合同无法评估属性是否是确定性的)而是在对象周围创建了 Pure 包装器(恰好是Nullable<Int64>)没有帮助。
第一个和第三个测试用例之间是否有区别,或者我认为它们是等价的是否正确,只是静态检查器无法正确评估第三种情况?
//Works
private Int64? _violations = null;
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(CheckIsValid(_violations));
}
[Pure]
public static Boolean CheckIsValid(Int64? value)
{
return (value.HasValue ? value.Value >= 0 : true);
}
public Class1(Int64 violations)
{
Contract.Requires(violations >= 0);
Contract.Ensures(CheckIsValid(_violations));
_violations = violations;
}
//Doesn't work, not provably deterministic
private Int64? _violations = null;
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(_violations.HasValue ? _violations.Value >= 0 : true);
}
public Class1(Int64 violations)
{
Contract.Requires(violations >= 0);
Contract.Ensures(_violations.HasValue ? _violations.Value >= 0 : true);
_violations = violations;
}
//Also doesn't work, even though it's provably deterministic
private PureNullableInt64 _violations = null; //A wrapper class around Int64? with [Pure] getters
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(_violations.HasValue ? _violations.Value >= 0 : true);
}
public Class1(Int64 violations)
{
Contract.Requires(violations >= 0);
Contract.Ensures(_violations.HasValue ? _violations.Value >= 0 : true);
_violations = violations;
}