6

私は 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.

これは Code Contracts の制限ですか、それとも間違っていますか? 私たちのプロジェクトには多くのインターフェース継承があり、この問題を回避する方法がわからない場合、これは Code Contracts の契約違反のように感じます。

4

1 に答える 1

10

それ以外の:

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

契約を継承するだけです。

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

で新しいメソッドのコントラクトを提供するだけで済みITwoます。からのコントラクトはIOneContract自動的に継承され、継承されたすべてのIOneメソッドを抽象として宣言できます。実際、onのコントラクトを提供することはできません。そうしないと、CCが文句を言います:)IOneITwoContract

たとえば、これがある場合:

[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; }
    }
}
于 2010-07-08T04:58:24.723 に答える