代码契约:抽象类中的不变量

Dyn*_*ike 9 c# abstract-class invariants code-contracts

我在使用带有代码约定的不变量时遇到了问题.我想在我的抽象类中定义一个Invariant,但它只是被忽略了.下面的代码显示了我的界面和抽象类.

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我在我的Point类中实现这个接口并从中创建一个对象.这应该至少在运行时失败.

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我将Invariant移动到Point-Class时,它工作正常.所有其他前置或后置条件也正常.

难道不能在抽象类中使用不变量,或者我做错了吗?

Kei*_*ith 2

接口不支持不变量。(您的问题标题是“抽象类中的不变量”,但问题的关键在于接口。)

我的猜测是,这是因为不变量需要状态,但接口没有状态。我确信代码合约团队可以解决这个问题,我希望他们这么做,因为这将是一个很棒的功能。

要解决此限制,您可以:

  • 将不变方法添加到派生类(class Point等)。
  • 或者,将 setter 添加到抽象类属性中,并在 setter 中实现契约逻辑。