协方差和向上转换之间的区别 [英] Difference between covariance and upcasting
问题描述
协方差和向上转换之间有什么区别,或者更具体地说,为什么它们的名称不同?
What is the difference between covariance and upcasting, or, more specifically, why are they given different names?
我见过以下称为向上转换"的示例:
I've seen the following example referred to as 'upcasting':
string s = "hello";
object o = s; //upcast to 'string' to 'object'
然而,我看到以下称为协方差":
Whereas, the following I have seen called 'covariance':
string[] s = new string[100];
object[] o = s;
IEnumerable<string> ies = new List<string>();
IEnumerable<object> ieo = ies;
现在,在我未经训练的眼睛看来,协方差似乎与向上转换相同,只是它指的是集合的转换.(对于逆变和向下转换,可以做出类似的声明).
Now, to my untrained eye, covariance seems to be the same as upcasting, except that it refers the casting of collections. (And of a similar statement can be made regarding contravariance and downcasting).
真的那么简单吗?
推荐答案
现在,在我未经训练的眼睛看来,协方差似乎与向上转换相同,只是它指的是集合的转换.(对于逆变和向下转换,可以做出类似的声明).
Now, to my untrained eye, covariance seems to be the same as upcasting, except that it refers the casting of collections. (And of a similar statement can be made regarding contravariance and downcasting).
真的那么简单吗?
协方差与向上转换无关,尽管我明白你为什么认为它是相关的.
Covariance isn't about upcasting, although I can see why you think it's related.
协方差是关于以下非常简单的想法.假设您有一个 IEnumerable
类型的变量 derivedSequence
.假设您有一个 IEnumerable
类型的变量 baseSequence
.这里,Derived
派生自 Base
.然后,通过协方差,以下是合法赋值,并发生隐式引用转换:
Covariance is about the following very simple idea. Let's say you have a variable derivedSequence
of type IEnumerable<Derived>
. Let's say you have a variable baseSequence
of type IEnumerable<Base>
. Here, Derived
derives from Base
. Then, with covariance, the following is a legal assignment, and an implicit reference conversion occurs:
baseSequence = derivedSequence;
请注意,这不是向上转换.IEnumerable
不是从 IEnumerable
派生的.相反,协方差允许您将变量 derivedSequence
的值分配给变量 baseSequence
.这个想法是可以从 Derived
类型的对象分配 Base
类型的变量,并且由于 IEnumerable
在其参数中是协变的,IEnumerable
类型的对象可以分配给 IEnumerable
类型的变量.
Note that this is not upcasting. It is not the case that IEnumerable<Derived>
derives from IEnumerable<Base>
. Rather, it is covariance that allows you to assign the value of the variable derivedSequence
to the variable baseSequence
. The idea is that variables of type Base
can be assigned from objects of type Derived
, and since IEnumerable<T>
is covariant in its parameter, objects of type IEnumerable<Derived>
can be assigned to variables of type IEnumerable<Base>
.
当然,我还没有真正解释什么是协方差.一般来说,协方差是关于以下简单的想法.假设您有一个从类型到类型的映射 F
(我将用 F
表示这个映射;给定类型 T
映射 F
下的图像是 F
.)假设这个映射具有以下非常特殊的属性:
Of course, I haven't yet really explained what covariance is. In general, covariance is about the following simple idea. Let's say you have a mapping F
from types to types (I'll denote this mapping by F<T>
; given a type T
its image under the mapping F
is F<T>
.) Let's say that this mapping has the following very special property:
如果X
与Y
赋值兼容,那么F
与F
赋值兼容代码>以及.
if
X
is assignment compatible withY
, thenF<X>
is assignment compatible withF<Y>
as well.
在这种情况下,我们说 F
在其参数 T
中是协变的.(这里,要说A
是与 B
兼容的赋值",其中 A
和 B
是引用类型意味着 B
的实例可以存储在 A
类型的变量中.)
In this case, we say that F
is covariant in its parameter T
. (Here, to say that "A
is assignment compatible with B
" where A
and B
are reference types means that instances of B
can be stored in variables of type A
.)
在我们的例子中,IEnumerable
在 C# 4.0 中,从 IEnumerable
的实例到 IEnumerable
的隐式引用转换code> 如果 Derived
是从 Base
派生的.保留了赋值兼容性的方向,这就是为什么我们说 IEnumerable
在其类型参数中是协变的.
In our case, IEnumerable<T>
in C# 4.0, an implicit reference conversion from instances of IEnumerable<Derived>
to IEnumerable<Base>
if Derived
is derived from Base
. The direction of assignment compatibility is preserved, and this is why we say that IEnumerable<T>
is covariant in its type parameter.
这篇关于协方差和向上转换之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!