【发布时间】:2019-03-13 20:44:59
【问题描述】:
我们有一个接口来处理具有非常简单定义的 DAL:
interface IRepository<T> : IQueriable<T> // so we can read data from database
{
Save(T document); // dozen of methods here
}
大多数情况下,我们使用两种实现方式:真实版本和内存版本进行单元测试。这是其中一类的声明:
public RealRepository : IRepository<AccountEntity> { ... }
// typical IOC usage
services.AddSingleton<IRepository<AccountEntity>, RealRepository<AccountEntity>>();
现在我们正在努力将主代码库拆分为项目的自定义版本,我们需要数据中的自定义字段和存储库中的偶尔自定义行为。大多数类都可以使用基本实现,但其他类则需要特定的实现。所以我的目标是获得以下服务:
var repository = new RealRepository<CustomAccountEntity>();
services.AddSingleton(IRepository<AccountEntity>, repository);
// for new classes
services.AddSingleton(IRepository<CustomAccountEntity>, repository);
我尝试将 out T 添加到 IRepository,但我在输入参数中使用了 T,这导致编译时出现“无效方差”错误。
我可以通过向接口添加第二个类型参数来查看解决方案,如下所示:
IRepository<TBase, out TChild> : IQueriable<TChild> {
Save (T document);
}
最后,问题:如何使更改 100% 向后兼容?
我尝试了什么:
- 添加
IRepository<T>: IRepository<T,T>-> 符合要求,但RealRepository不再实现IRepository。 - 在实现中添加 2 个接口:
public class RealRepository<TBase, TChild>: IRepository<TBase, TChild>, IRepository<TChild>但这会导致编译错误“无法同时实现 ... 和 ...,因为它们可能会针对某些类型参数替换进行统一”
【问题讨论】:
标签: c# .net generics interface covariance