我的界面(部分内容):
public interface IRepository
{
Task<T> Insert<T>(T item) where T : class, ISyncable;
}
我的实施:
public class TableStorageRepository: IRepository
{
public async Task<T> Insert<T>(T item) where T: class, ISyncable
{
TableOperation.Insert(item);
}
}
我的实施无效,因为TableOperation.Insert
需要ITableEntity
以及ISyncable
我无法将我的界面更新为:Task<T> Insert<T>(T item) where T : class, ISyncable, ITableEntity;
因为那时我的其他IRepository实现将不再起作用。
我无法将ITableEntity
添加到我的实现参数约束中,因为那时约束不再与接口约束匹配,这会导致以下错误:
“方法的参数类型'T'的约束......”
有一种优雅的方法来解决这个问题吗?
答案 0 :(得分:0)
恕我直言你的设置是错的。你打破了Liskov substitution principle。
您的IRepository
界面定义了合约。该合同规定,只要T
为T
且参考类型,就可以插入任何ISyncable
。
您的班级TableStorageRepository
打破该合约。它无法处理任何ISyncable
,它只能处理ITableEntity
。它没有业务实现它无法实现的接口,所以不要这样做。
你可以通过凌乱的运行时类型检查来解决这个问题,但它可以解决这个问题。你的构建块很糟糕,所以你在它们上面构建的所有东西都是最不稳定的。
一个有效的缓解策略,当你无法避免陷入这个位置时,正在让界面定义一个方法,告诉消费者某些操作是否有效:bool CanInsert<T>
但是你说你不能修改界面,所以这不是一个选项。