嵌套接口的逆变问题
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
或重新思考问题。
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
或重新思考问题。