嵌套接口的逆变问题

Contravariance troubles with nested interfaces

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>

但这似乎不可能。

谁能解释这是为什么?

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

Covariance enables you to use a more derived type than that specified by the generic parameter

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

out (generic modifier) (C# Reference)


具体来说,尽管看起来 IService<IModel>ServiceA : IService<ModelA>

不是一回事

out表示(粗略的)只能出现在输出位置。

请注意,这将严重限制您使用 T 可以做的事情。

如果你需要在IService中使用T(而且它不仅仅是IService中的return方法),那么你可能需要使用object 或重新思考问题。