Code Contracts in Interfaces are evaluated after Contracts in Class Implementations

I recently noticed an — at least for me — unexpected behaviour when working with Code Contracts in interfaces. When you define a contract for an interface (via ContractClassFor) and implement a class from that interface that contract is certainly enforced. However when you define additional requirements on that implementation class these contracts are evaluated BEFORE the interface contracts.

Here is a quick example to demonstrate the behaviour:

namespace biz.dfch.CS.Examples.CodeContracts
  public interface IInterfaceWithContract
    void Funcenstein(string parameter);

  abstract class ContractClassForIInterfaceWithContract : IInterfaceWithContract
    public void Funcenstein(string parameter)
      Contract.Requires(null != parameter);

  public class IInterfaceWithContractTest
    class InterfaceWithContractImpl : IInterfaceWithContract
      public void Funcenstein(string parameter)
        // more restrictive requirement than on interface


    public void CallingFuncensteinViolatesClassCodeContract()
      // Arrange
      var parameter = "arbitrary-string-other-than-edgar";

      // Act
      var sut = new InterfaceWithContractImpl();

We define an interface IInterfaceWithContract that does not accept null strings on its Funcenstein method. The actual class implementation InterfaceWithContractImpl now requires a string that must StartWith edgar (which is more restrictive). Now we run into a problem, that the class implementation is evaluated first, which means we possibly de-reference a null pointer which would normally lead to getting the dreaded object reference not set to an instance of an object (but which is encapsulated by the __ContractsRuntime+ContractException exception.
If we had checked the contract from the interface first we would have gotten a more meaningful message (indicating that the whole string is actually null). Now we just get the message that the string does not start with edgar.

>> Test method biz.dfch.CS.Examples.CodeContracts.IInterfaceWithContractTest.
>> CallingFuncensteinViolatesClassCodeContract threw exception:
>> System.Diagnostics.Contracts.__ContractsRuntime+ContractException:
>> Precondition failed: parameter.StartsWith(“edgar”)

Just something to keep in mind when troubleshooting.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: