接口参数约束

时间:2017-11-19 10:11:21

标签: c# interface constraints

我的界面(部分内容):

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'的约束......”

有一种优雅的方法来解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

恕我直言你的设置是错的。你打破了Liskov substitution principle

您的IRepository界面定义了合约。该合同规定,只要TT且参考类型,就可以插入任何ISyncable

您的班级TableStorageRepository 打破该合约。它无法处理任何ISyncable,它只能处理ITableEntity。它没有业务实现它无法实现的接口,所以不要这样做。

你可以通过凌乱的运行时类型检查来解决这个问题,但它可以解决这个问题。你的构建块很糟糕,所以你在它们上面构建的所有东西都是最不稳定的。

一个有效的缓解策略,当你无法避免陷入这个位置时,正在让界面定义一个方法,告诉消费者某些操作是否有效:bool CanInsert<T>但是你说你不能修改界面,所以这不是一个选项。