我想我在静态合同检查工具中发现了一个错误。除了用 标记整个事物之外,还有其他方法[ContractVerification(false)]
吗?
class Employee
{
public int? HierarchyLevel { get; private set; }
public Employee(int? level)
{
Contract.Requires<ArgumentException>(
(!level.HasValue)
||
level >= 0 && level <= 10);
Contract.Ensures(
(!HierarchyLevel.HasValue)
||
(HierarchyLevel.Value >= 0 && HierarchyLevel.Value <= 10));
this.HierarchyLevel = level; //unproven
// this doesnt work either
//if (!level.HasValue) {
// this.HierarchyLevel = new Nullable<int>();
//} else {
// this.HierarchyLevel = new Nullable<int>(level.Value);
//}
// can't even make the static checker shut up with that:
//Contract.Assume(
// (!HierarchyLevel.HasValue)
// ||
// (HierarchyLevel.Value >= 0 && HierarchyLevel.Value <= 10));
}
}
令人惊讶的是,以下版本有效。但我不想开始编写单一的代码或引入我自己的 Nullable 版本只是为了取悦合约验证工具。
class Employee2
{
public int HierarchyLevel { get; private set; }
public bool HasLevel { get; private set; }
public Employee2(int level, bool hasLevel)
{
Contract.Requires<ArgumentException>(!hasLevel || level >= 0 && level <=10);
if (hasLevel) {
HasLevel = true;
HierarchyLevel = level;
} else {
HasLevel = false;
HierarchyLevel = -1;
}
}
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(
(!HasLevel) ||
(HierarchyLevel >= 0 && HierarchyLevel <= 10));
}
}