【发布时间】:2014-12-01 13:01:55
【问题描述】:
我现在使用 Microsoft 代码合同有一段时间了,今天我偶然发现了一个尴尬的案例。我的问题是 - 有没有一种优雅的方法来解决这种情况?
假设我有一个用于存储库的简单特征接口,如下所示:
[ContractClass(typeof(CanAddContract)]
public interface ICanAdd {
void Add(object entity);
}
此合同,如属性中所示,如下所示:
[ContractClassFor(typeof(ICanAdd))]
internal abstract class CanAddContract {
public void Add(object entity) {
Contract.Requires(object != null); // guard against null argument
}
}
所以,现在我们有了一个类似的实体删除特征
[ContractClass(typeof(CanDeleteContract))]
public interface ICanDelete {
void Delete(object entity);
}
...和合同...
[ContractClassFor(typeof(ICanDelete))]
internal abstract class CanDeleteContract {
public void Delete(object entity) {
Contract.Requires(entity != null); // guard against null argument
}
}
这并没有错。但是由于接口表示存储库特征,它们被用于组成存储库接口:
public interface IEntityStore : ICanAdd, ICanDelete {
void SomeOtherMethodThatNeedsAContract();
}
现在呢?当我想为这个接口创建一个契约类时,我必须重新实现上面提到的两个契约类,因为在 C# 中不允许多重继承。这让我不得不为合同复制代码。想一想 - 在所有可能的情况下,这对我来说都是错误的。
我能做些什么呢?
【问题讨论】:
-
@MatthewWatson 这对我没有帮助,因为 ICanDelete(假设您链接的问题中的 ITwo)没有实现 ICanAdd (IOne)。它们是独立的、不相关的接口,而只有 IEntityStore 实现了两者(以及一些其他特定于 IEntityStore 的方法)。请仔细阅读问题。
-
当然对你有帮助。我正在添加一个答案,它准确地显示了你如何做到这一点。
-
@MatthewWatson 似乎我过于关注链接中提供的示例,而不是其背后的总体思路。您提供的答案完美无缺,所以谢谢! (也将其发布为答案。这样我可以给你一些想象的互联网点。)
标签: c# oop inheritance interface code-contracts