[NoBrainer] Code Contracts in Interfaces with abstract base classes will not trigger if override is not specified

Today I ran into a problem when all of a sudden my code contracts stopped working – as it seemed. In reality I was missing a simple override in the implementation of a class that derived from a base class.

But now for a a concrete example. Suppose you have the following scenario:

  1. ContractClassForIArbitraryObject
    this class holds the contract for the interface IArbitraryObject
  2. IArbitraryObject
    this interface declares the Invoke method
  3. ArbitraryObjectBase
    this abstract base class that might implement some default behaviour
  4. ArbitraryObjectImpl
    the actual implementation of the interface (via the base class)

Below you see an example implementation of the aforementioned classes:

[ContractClassFor(typeof(IArbitraryObject))]
abstract class ContractClassForIArbitraryObject : IArbitraryObject
{
  public bool IsActive { get; set; }

  public bool Invoke(object obj)
  {
    Contract.Requires(null != obj);

    return default(bool);
  }
}

[ContractClass(typeof(ContractClassForIArbitraryObject))]
public interface IArbitraryObject
{
  bool IsActive { get; set; }
  bool Invoke(object obj);
}

public abstract class ArbitraryObjectBase : IArbitraryObject
{
  public virtual bool IsActive { get; set; }

  public virtual bool Invoke(object obj)
  {
    if(!IsActive)
    {
      return false;
    }

    // some magic code
    var result = 0 == (obj.GetType().ToString().Length % 2);
    return result;
  }
}

public class ArbitraryObjectImpl : ArbitraryObjectBase
{
  public bool Invoke(object obj)
  {
    // some magic code ...

    return true;
  }
}

When we now try to Invoke a null object from our instantiated ArbitraryObjectImpl we should throw a Contract Exception as the pre-condition null != obj is not satisfied. However, the code will run just fine:

var arbitraryObjectImpl = new ArbitraryObjectImpl();
/// this will NOT throw a contract exception !!!
arbitraryObjectImpl.Invoke(default(object));

The reason for this is, that we forgot to specify override for the virtual method in our base class. IF we define the ArbitraryObjectImpl as shown in the example below (with the override on the Invoke method), CodeContracts will be checked and throw an exception (as expected):

public class ArbitraryObjectImpl : ArbitraryObjectBase
{
  public override bool Invoke(object obj)
  {
    // some magic code ...

    return true;
  }
}

The problem here really is not too hard to solve: just add the override operator and we are done. But what is really annoying here is, that we do not get a compiler error in case we forgot the override. And it becomes rather difficult to spot once we missed the operator. (We certainly can test it by writing unit tests …)

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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: