我正在尝试将Code Contracts集成到一些现有代码中,到目前为止大部分内容都很好。我面临的问题是我在一个接口上设置了合同,一个实现将实现委托给一个Func<>传递给类的构造函数,类似于以下内容:
[ContractClass(typeof(IFooContract))]
public interface IFoo
{
object Bar();
}
[ContractClassFor(typeof(IFoo))]
public abstract class IFooContract : IFoo
{
object IFoo.Bar()
{
Contract.Ensures(Contract.Result<object>() != null);
throw new NotImplementedException();
}
}
public class DelegatedFoo : IFoo
{
public DelegatedFoo(Func<object> barImplementation)
{
Contract.Requires(barImplementation != null);
_barImplementation = barImplementation;
}
private readonly Func<object> _barImplementation;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_barImplementation != null);
}
public object Bar()
{
//"ensures unproven: Contract.Result<object>() != null" here.
return _barImplementation();
}
}
静态分析器报告错误“确保未经证实:Contract.Result()!= null”。我可以在Func&lt;&gt;上定义合约吗? (以及Action&lt;&gt;的扩展名)?
这是最好的解决方案吗?
public class DelegatedFoo : IFoo
{
public DelegatedFoo(Func<object> barImplementation)
{
Contract.Requires(barImplementation != null);
_barImplementation = barImplementation;
}
private readonly Func<object> _barImplementation;
[ContractInvariantMethod]
private void ObjectInvariants()
{
Contract.Invariant(_barImplementation != null);
}
public object Bar()
{
var result = _barImplementation();
Contract.Assume(result != null);
return result;
}
}
答案 0 :(得分:0)
那么,总是是否可以控制传入的Func<object>
个实例?如果是这样,Func<object>
参数引用的每个函数都需要定义Contract.Ensures(Contract.Result<object>() != null)
后置条件。
如果你有一个Action
参数,那也是如此。
另外,我绝对不会使用Contract.Assume(result != null)
。你确定你永远不会返回null吗?如果你做了会怎么样?请尝试将其更改为Contract.Assert(result != null)
。如果您可以控制Func<object>
参数并使用后置条件,那么您应该能够在public object Bar()
方法上指定后置条件,并放弃对任何断言或假设的需要。
最后,您可能需要考虑将Contract.Ensures(_barImplementation == barImplementation)
添加到DelegatedFoo
的构造函数中,但我认为后置条件由定义的不变量覆盖。我总是喜欢明确 - 它肯定不会受到伤害,特别是在涉及静态分析仪的情况下。