Контракты кода: Как иметь дело с наследуемыми интерфейсами?

Я использую Контракты Кода MS и столкнулся с препятствием с использованием интерфейсного наследования и атрибутов 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 имел бы существенный объем кода в нем для необходимых проверок.

Я не хочу копировать все это в 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.

Действительно ли это - ограничение в Контрактах Кода, или я делаю его неправильно? У нас есть большое интерфейсное наследование в нашем проекте, и это чувствует себя подобно недопустимому для Контрактов Кода, если я не могу выяснить, как работать вокруг этой проблемы.

6
задан scobi 7 July 2010 в 18:40
поделиться

1 ответ

Вместо:

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

Просто наследуйте контракт:

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

Вам нужно предоставить контракты только на методы, которые являются новыми в ITwo. Контракты из IOneContract будут наследоваться автоматически, и вы можете объявить все наследуемые методы IOne абстрактными - на самом деле, вы не можете предоставить контракты для IOne на ITwoContract, иначе 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; }
}

Тогда эта реализация скажет "unproven contract" на обоих методах, как и ожидалось:

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

    public int Thing2
    {
        get { return 0; }
    }
}
10
ответ дан 10 December 2019 в 00:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: