Ara*_*h-s 1 .net c# generics contravariance nested-generics
interface IModel
{
}
class ModelA : IModel
{
}
interface IService<T> where T: IModel
{
}
class ServiceA : IService<ModelA>
{
}
Run Code Online (Sandbox Code Playgroud)
鉴于上面的类和接口的定义,以下工作:
IModel model = new ModelA();
Run Code Online (Sandbox Code Playgroud)
表明ModelA可以强制转换为其接口IModel
以下也适用:
IService<ModelA> service1 = new ServiceA();
Run Code Online (Sandbox Code Playgroud)
表明ServiceA可以强制转换为其接口IService<ModelA>
但是,以下情况会失败:
IService<IModel> service2 = new ServiceA();
Run Code Online (Sandbox Code Playgroud)
错误消息表明ServiceA不能隐式转换为IService<IModel>
我对此感到惊讶,因为:
ModelA可以转换为IModel,并且
ServiceA可以转换为IService<IModel>
我期望发生以下情况:
ServiceA-> IService<ModelA>->IService<IModel>
但这似乎不可能。
有人能解释为什么吗?
这里唯一真正的选择是out对泛型类型应用修饰符,IService使其成为协变的
协方差使您能够使用比泛型参数指定的派生类型更多的类型
interface IService<out T> where T : IModel
{
}
Run Code Online (Sandbox Code Playgroud)
具体来说,尽管看起来IService<IModel>与ServiceA : IService<ModelA>
out意思是(粗略地说),它只能出现在输出位置。
但请注意,这将严重限制您可以使用T.
如果您需要使用Tin IService(并且它不仅仅是 in 方法的返回IService),那么您可能需要使用object或重新考虑问题。