Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code Contracts: Invariants in abstract class

I have encountered a problem while using Invariants with Code Contracts. I want to define an Invariant within my abstract class but it is simply ignored. The code below shows my interface and the abstract class.

[ContractClass(typeof(IPointContract))]
interface IPoint
{
    int X { get; }
    int Y { get; }
}

[ContractClassFor(typeof(IPoint))]
abstract class IPointContract : IPoint
{

    public int X
    {
        get { return 0; }

    }

    public int Y
    {
        get { return 0; }
    }

    [ContractInvariantMethod]
    private void PointInvariant()
    {
        Contract.Invariant(X > Y);
    }
}

Afterwards, I implement this interface within my Point class and create an object from it. This should at least fail during runtime.

class Point : IPoint
{
    public Point(int X, int Y)
    {
        this._x = X;
        this._y = Y;
    }

    private int _x;
    public int X
    {
        get { return _x; }
    }

    private int _y;
    public int Y
    {
        get { return _y; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Point p = new Point(1, 2);
    }
}

When I move the Invariant to the Point-Class, it works fine. All other pre- or post conditions are working fine too.

Is it not possible to have Invariants within an abstract class or am I doing it wrong?

like image 531
Dynamike Avatar asked Mar 18 '15 13:03

Dynamike


1 Answers

Invariants are not supported on interfaces. (Your question title is "Invariants in abstract class" but the crux of the problem is with the interface.)

My guess is that this is because invariants require state but interfaces don't have state. I'm sure the code contracts team can work around this and I wish they would because this would be a great feature to have.

To work around this limitation you could:

  • Add the invariant method to the derived classes (class Point, etc.).
  • Or, add setters to the abstract class properties and implement the contract logic in the setters.
like image 51
Keith Avatar answered Nov 16 '22 15:11

Keith