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

发布于 2024-09-08 05:49:15 字数 822 浏览 4 评论 0原文

我正在使用 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 { }

假设 IOne 和 ITwo 是实质性接口。因此 IOneContract 中将包含大量代码用于必要的检查。

我不想为 IOne 接口重复 ITwoContract 中的所有内容。我只想为 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.

这是代码合同中的限制还是我做错了?我们的项目中有很多接口继承,如果我不知道如何解决这个问题,这感觉就像代码契约的交易破坏者。

I'm using MS Code Contracts and have run into a snag with using interface inheritance and ContractClassFor attributes.

Given these interfaces and contract classes:

[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 { }

Let's say that IOne and ITwo are substantial interfaces. So IOneContract would have a significant amount of code in it for the necessary checks.

I don't want to duplicate all of that in ITwoContract for the IOne interfaces. I only want to add new contracts for the ITwo interfaces. Inheriting one contract class from another seems the likely way to reuse that code. Yet I get the following error:

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.

Is this a limitation in Code Contracts or am I doing it wrong? We have a lot of interface inheritance in our project and this feels like a deal breaker for Code Contracts if I can't figure out how to work around this issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别再吹冷风 2024-09-15 05:49:15

而不是:

[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : IOneContract, ITwo { }

仅继承契约:

[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : ITwo { }

您只需为 ITwo 中新增的方法提供契约。来自 IOneContract 的契约将自动继承,并且您可以将所有继承的 IOne 方法声明为抽象方法 - 事实上,您不能为以下对象提供契约ITwoContract 上的 IOne,否则 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; }
}

那么此实现将在两种方法上显示“未经证实的合同”,正如预期的那样:

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

    public int Thing2
    {
        get { return 0; }
    }
}

Instead of:

[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : IOneContract, ITwo { }

Just inherit the contract:

[ContractClassFor(typeof(ITwo))]
abstract class ITwoContract : ITwo { }

You only need to provide contracts on the methods which are new in ITwo. The contracts from IOneContract will be inherited automatically, and you can declare all the inherited IOne methods as abstract — in fact, you cannot provide contracts for IOne on ITwoContract, or CC will complain :)

For example, if you have this:

[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; }
}

Then this implementation will say "unproven contract" on both methods, as expected:

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

    public int Thing2
    {
        get { return 0; }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文