关于 C# 协方差的问题 [英] Question about C# covariance

查看:25
本文介绍了关于 C# 协方差的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中:

interface I1 { }
class CI1: I1 { }

List<CI1> listOfCI1 = new List<CI1>();

IEnumerable<I1> enumerableOfI1 = listOfCI1; //this works

IList<I1> listofI1 = listOfCI1; //this does not

我可以将我的listOfCI1"分配给 IEnumerable(由于协方差)

I am able to assign my "listOfCI1" to an IEnumerable<I1> (due to covariance)

但是为什么我不能将它分配给 IList?就此而言,我什至不能执行以下操作:

But why am I not able to assign it to an IList<I1>? For that matter, I cannot even do the following:

List<I1> listOfI12 = listOfCI1;

协方差不应该允许我将派生类型分配给基类型吗?

Shouldn't covariance allow me to assign a derived type to a base type?

推荐答案

简单地说,IList 不是协变的,而 IEnumerable 是协变的.这就是为什么...

Simply put, IList<T> is not covariant, whereas IEnumerable<T> is. Here's why...

假设 IList 协变的.下面的代码显然不是类型安全的……但是您希望错误在哪里?

Suppose IList<T> was covariant. The code below is clearly not type-safe... but where would you want the error to be?

IList<Apple> apples = new List<Apple>();
IList<Fruit> fruitBasket = apples;
fruitBasket.Add(new Banana()); // Aargh! Added a Banana to a bunch of Apples!
Apple apple = apples[0]; // This should be okay, but wouldn't be

有关很多差异的详细信息,请参阅 Eric Lippert 的 博文系列,或观看视频关于与 NDC 的差异的讨论.

For lots of detail on variance, see Eric Lippert's blog post series on it, or watch the video of my talk about variance from NDC.

基本上,只有在保证安全的情况下才允许变化(并且以保留表示的方式,这就是为什么您不能将 IEnumerable 转换为 IEnumerable<;object> - 装箱转换不保留表示).

Basically, variance is only ever allowed where it's guaranteed to be safe (and in a representation-preserving way, which is why you can't convert IEnumerable<int> into IEnumerable<object> - the boxing conversion doesn't preserve representation).

这篇关于关于 C# 协方差的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆