嵌套接口的矛盾

时间:2019-02-22 10:58:14

标签: c# .net generics contravariance nested-generics

interface IModel
{ 
}

class ModelA : IModel
{
}

interface IService<T> where T: IModel
{
}

class ServiceA : IService<ModelA>
{
}

鉴于上面的类和接口的定义, 以下作品:

IModel model = new ModelA();

表明可以将ModelA强制转换为其接口IModel

以下内容也适用:

IService<ModelA> service1 = new ServiceA();

表明可以将ServiceA强制转换为其接口IService<ModelA>

但是,以下操作失败:

IService<IModel> service2 = new ServiceA();

错误消息指出,不能ServiceA隐式转换为IService<IModel>

我对此感到惊讶,因为:
ModelA可以强制转换为IModel,并且
ServiceA可以强制转换为IService<IModel>
我原以为会发生以下情况:
ServiceA-> IService<ModelA>-> IService<IModel>

但这似乎不可能。

有人对此有一个解释吗?

1 个答案:

答案 0 :(得分:4)

您在这里唯一的真实选择是在out的通用类型上应用IService修饰符,使其成为 Covariant

  

协方差使您可以使用比指定类型更多的派生类型   通过通用参数

interface IService<out T> where T : IModel
{
}

out (generic modifier) (C# Reference)


具体来说,IService<IModel>ServiceA : IService<ModelA>并不是一样

out意味着(大致来说),它只能出现在输出位置。

请注意,这将严重限制您可以T使用的功能。

如果您需要在T中使用IService(并且不仅是IService中方法的返回),那么您可能需要使用object或重新考虑问题