I have a situation I don't know how it's supposed to be solved.
According to the user manual section 3, a contractmethod, i.e. Require
or Ensure
, is not allowed in overriding methods/properties or interface implementations. The contract methods should be declared in the root virtual/abstract method and since you can't declare code in an abstract method, you have to work with the ContractClassAttribute
and ContractClassForAttribute
. The same goes for contractmethods for interfacemembers(and their implementations).
But what if I want to use an interface I haven't created myself? For example IList<T>
doesn't implement these contract methods, but I can't set the ContractClassAttribute
on it either. How should I do parametervalidation in for example the implementation of IList<T>.this[int]
? The following solutions aren't allowed:
T IList<T>.this[int i]
{
get
{
Contract.Requires(i >= 0);//not allowed
if (i < 0)
throw new ArgumentException();
Contract.EndContractBlock();//also not allowed
...
}
}
Are the legacy if-then-throw statements without EndContractBlock
the only solution?
First of all, IList<T> already specifies that precondition. I just tried it to be sure: "Precondition failed: index >= 0".
Furthermore, as I understand it, post conditions are allowed, only preconditions aren't.
If, you would still like to add other preconditions, I believe this answers your question: http://social.msdn.microsoft.com/Forums/en/codecontracts/thread/af403bbc-ca4e-4546-8b7a-3fb3dba4bb4a
It basicly comes down to the fact that you are not meant to do so, as that would defy the purpose of code contracts.