问题
I understand that I cannot add preconditions on an interface implementation. I have to create a contract class where I define contracts on elements that are seen by the interface.
But in the following case, how can add a contract on an internal state of the implementation that is therefore not known at the interface definition level ?
[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);
<...>
}
}
回答1:
You can't - that postcondition isn't appropriate for all implementations of IFoo
, because it's not declared in IFoo
. You can only refer to members of the interface (or other interfaces it extends).
You should be able to add it in Foo
though, because you're adding a postcondition (Ensures
) rather than a precondition (Requires
).
You can't add an implementation-specific precondition because then a caller wouldn't be able to know whether or not they were going to violate the contract:
public void DoSomething(IFoo foo)
{
// Is this valid or not? I have no way of telling.
foo.Do(bar);
}
Basically, contracts aren't allowed to be "unfair" to callers - if the caller violates a precondition, that should always indicate a bug rather than something they couldn't have predicted.
来源:https://stackoverflow.com/questions/1385485/add-contract-to-interface-implementation