我正在使用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会有大量的代码用于必要的检查。
我不想在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.
这是代码合约的限制还是我做错了?我们的项目中有很多接口继承,如果我不知道如何解决这个问题,这就像代码合同的交易破坏者。
答案 0 :(得分:10)
而不是:
[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; }
}
然后,这个实现将对这两种方法说“未经证实的合同”,如预期的那样:
class Two : ITwo
{
public int Thing
{
get { return 0; }
}
public int Thing2
{
get { return 0; }
}
}