据我所知,我不能在接口实现上添加前置条件。我必须创建一个契约类,我在其中定义接口所见元素的契约。
但是在下面的例子中,如何在实现的内部状态上添加一个合同,因此在接口定义级别是未知的?
[ContractClass(typeof(IFooContract))]
interface IFoo
{
void Do(IBar bar);
}
[ContractClassFor(typeof(IFoo))]
sealed class IFooContract : IFoo
{
void IFoo.Do(IBar bar)
{
Contract.Require (bar != null);
// ERROR: unknown property
//Contract.Require (MyState != null);
}
}
class Foo : IFoo
{
// The internal state that must not be null when Do(bar) is called.
public object MyState { get; set; }
void IFoo.Do(IBar bar)
{
// ERROR: cannot add precondition
//Contract.Require (MyState != null);
<...>
}
}
答案 0 :(得分:3)
你不能 - 后置条件不适合IFoo
的所有实现,因为它没有在IFoo
中声明。您只能引用接口的成员(或其扩展的其他接口)。
您应该可以在Foo
中添加它,因为您要添加后置条件(Ensures
)而不是前置条件 (Requires
)。
您无法添加特定于实现的前置条件,因为然后调用者无法知道他们是否会违反合同:
public void DoSomething(IFoo foo)
{
// Is this valid or not? I have no way of telling.
foo.Do(bar);
}
基本上,合同不允许对呼叫者“不公平” - 如果呼叫者违反前提条件,则应始终指出错误而不是他们无法预测的错误。