【发布时间】:2012-08-15 12:14:47
【问题描述】:
我已设法将其归结为以下测试用例,但我想知道这是否是 C# 代码合同中静态检查器的限制,还是我缺少的东西。当我尝试使用一种代码风格来证明合同时,它会抛出 invariant unproven 警告,但(我认为是)证明它可以正常工作的等效方法。
最初我认为这可能是因为我没有使用具有 Pure 属性的对象(因此代码合同无法评估属性是否是确定性的)而是在对象周围创建了 Pure 包装器(恰好是 Nullable
第一个和第三个测试用例之间是否有区别,或者我认为它们是等价的是否正确,只是静态检查器无法正确评估第三个用例?
//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;
}
【问题讨论】:
-
在挑剔之前:这是测试代码。不要担心格式、变量名、标准等,除非它们与静态分析相关!
-
这不是一个答案,但静态 CC 检查器非常弱。它不能证明对实际程序有用的属性。
标签: c# code-contracts static-code-analysis deterministic