代码契约:如何处理继承的接口?

sco*_*obi 6 code-contracts

我正在使用MS Code Contracts,并且使用接口继承和ContractClassFor属性遇到了麻烦.

给定这些接口和合同类:

[ContractClass(typeof(IOneContract))]
interface IOne { }
[ContractClass(typeof(ITwoContract))]
interface ITwo : IOne { }

[ContractClassFor(typeof(IOne))]
abstract class IOneContract : IOne { }
[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : IOneContract, ITwo { }
Run Code Online (Sandbox Code Playgroud)

让我们说IOne和ITwo是实质性的接口.所以IOneContract会有大量的代码用于必要的检查.

我不想在ITwoContract中为IOne接口复制所有这些内容.我只想为ITwo接口添加新合同.从另一个合同类继承似乎是重用该代码的可能方式.但是我收到以下错误:

EXEC : warning CC1066: Class 'ITwoContract' is annotated as being the contract for the interface 'ITwo' and cannot have an explicit base class other than System.Object.
Run Code Online (Sandbox Code Playgroud)

这是代码合同中的限制还是我做错了?我们的项目中有很多接口继承,如果我无法弄清楚如何解决这个问题,这就像是Code Contracts的交易破坏者.

por*_*ges 10

代替:

[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : IOneContract, ITwo { }
Run Code Online (Sandbox Code Playgroud)

只需继承合同:

[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : ITwo { }
Run Code Online (Sandbox Code Playgroud)

您只需要提供有关新方法的合同ITwo.从这些合同IOneContract将自动继承,并且可以声明所有继承的IOne方法为抽象的-事实上,你不能对提供的合同IOneITwoContract,还是CC会抱怨:)

例如,如果你有这个:

[ContractClass(typeof (IOneContract))]
interface IOne
{
    int Thing { get; }
}

[ContractClass(typeof (ITwoContract))]
interface ITwo : IOne
{
    int Thing2 { get; }
}

[ContractClassFor(typeof (IOne))]
abstract class IOneContract : IOne
{
    public int Thing
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() > 0);
            return 0;
        }
    }
}

[ContractClassFor(typeof (ITwo))]
abstract class ITwoContract : ITwo
{
    public int Thing2
    {
        get
        {
            Contract.Ensures(Contract.Result<int>() > 0);
            return 0;
        }
    }

    public abstract int Thing { get; }
}
Run Code Online (Sandbox Code Playgroud)

然后,这个实现将按照预期在两种方法上说"未经证实的合同":

class Two : ITwo
{
    public int Thing
    {
        get { return 0; }
    }

    public int Thing2
    {
        get { return 0; }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 啊! "你可以将所有继承的IOne方法声明为抽象"位是我缺少的关键部分.谢谢. (3认同)