基本上,我有一个虚拟方法将某些强制性后置条件传播到子类。这是一个简化版本和静态检查器生成的奇怪警告(编辑 - 我的例子不完整。现在就是这样):
public abstract class InitializerClass
{
protected bool _initialized
public bool IsInitialized
{
get { return _initialized; }
}
public virtual void Initialize()
{
//Warning CodeContracts: Missing precondition in an externally visible
//method. Consider adding Contract.Requires(this.IsInitialized); for
//parameter validation
Contract.Ensures(IsInitialized);
}
}
这是另一个类:
public abstract class OrderingClass
{
protected bool _ordered
public bool IsOrdered
{
get { return _ordered; }
}
public override void Initialize()
{
//Message CodeContracts: Suggested assume: Contract.Assume(this.IsOrdered);
Contract.Ensures(IsOrdered);
}
}
实际上,这两个警告都指向方法的结束大括号,在紧跟Contract.Ensure调用的行中。我的代码出了什么问题?
答案 0 :(得分:0)
您收到此错误,因为代码合同无法验证调用Initialize()
是否会导致IsInitialized
返回true。这是因为Initialize()
正文中没有将IsInitialized
的值设置为true
的代码,因此分析器会警告您代码假定IsInitialized
是<{1}}进入true
后,您应该明确这个前提条件。
有两种方法可以消除警告。
首先,添加建议的前提条件:
Initialize()
其次,将public virtual void Initialize()
{
Contract.Requires(IsInitialized);
Contract.Ensures(IsInitialized);
}
的值设置为IsInitialized
:
true
您需要向public virtual void Initialize()
{
IsInitialized = true;
Contract.Ensures(IsInitialized);
}
添加私有设置器才能使上述代码生效。
IsInitialized
简单地在public bool IsInitialized
{
get { return _initialized; }
private set { __initialized = value; }
}
中设置_initialized = true
可能不会允许代码合同验证后置条件,因此添加私有设置器。但是,假设将以下合同添加到Initialize()
可能会否定添加属性设置器的需要:
IsInitialized
出于同样的原因,您在public bool IsInitialized
{
get
{
Contract.Ensures(Contract.Result<bool>() ^ !_initialized);
return _initialized;
}
}
收到警告。代码合同建议使用OrderingClass
,因为您无法在替换中使用Contract.Assume()
。