以下总结了我对C#方差的理解。如果您能告诉我我出了什么问题,我将不胜感激,因为我读了Eric Lippert撰写的Exact rules for variance validity上的文章,而我大部分都听不懂。
方差是这样一种想法,即从一种类型到另一种类型的转换(或投影,如Eric Lippert所述)可以保留分配兼容性(协方差),也可以逆转(协方差),或者既不保留也不逆转(不变性)。
那是;如果I是T中的协变变换,其中T是一组类型,则对于T中的任何T1和T2类型,如果T1可分配给T2,则I<T1>
可分配给I<T2>
。如果我是反对的,结果将被恢复。如果我不变,则I<T1>
都不可分配给I<T2>
或相反。
现在,类型是协变还是逆变是什么意思?方差不是类型投影的属性,也不是类型本身的属性。
泛型I<out T, in U>
在T上协变而在U上协变是什么意思?
另外,什么是协方差有效性逆转变异有效性的方向,而协方差有效性逆转变异有效性均值的方向?
最佳答案
现在,类型是协变还是逆变是什么意思?方差不是类型投影的属性,也不是类型本身的属性吗?
是的,您可以找到。好吧,您快要出现了。方差是关于类型给定关系的类型投影的属性。
考虑以下语句:
从引用类型T
映射到类型IEnumerable<T>
的投影保留了分配兼容性关系的方向,因此该投影是协变的。
从T
到IEnumerable<T>
的投影在T中是协变的。IEnumerable<T>
在T
中是协变的。IEnumerable<T>
是协变的。
我们说第四个;我们的意思是第一个。我们假设通过“ IEnumerable<T>
是协变的”,从上下文中可以清楚看出什么是投影(从T
到IEnumerable<T>
)以及保留的关系是什么(分配兼容性)。这样说比较容易。
在您提到的文章中,我一开始甚至比这更卑鄙。我使用“协变”基本上是指“可以某种方式参与协变转换”。但是,“协变量有效”等的定义是精确的。如果称其为“协变有效”使它难以理解,则将其命名为:
如果类型X是指针,非泛型,带有Frobby元素类型的数组,或者泛型类型(其中每个“输入”类型参数为Blobby,每个“输出”类型参数为Frobby),则将其称为Frobby类型。 ,所有其他类型参数都是Frobby和Blobby。如果它是指针,非泛型,具有Blobby元素类型的数组,或者泛型类型(其中每个“输入”类型参数为Frobby,每个“输出”类型参数为Blobby,并且每个其他类型的参数是Frobby和Blobby。
在那里,我们根本不使用“协变”或“相反”两个词,并且我们对Frobby和Blobby都有精确的定义。
通用类型I<out T, in U>
在T
上协变而在U
上协变是什么意思?
同样,这只是一个简短的形式。第一部分意味着对于任何固定的U
,从引用类型T
到I<T, U>
的投影都是保留分配兼容性方向的投影。如果X
是与Y
兼容的分配,并且Z
是任何类型,则I<X, Z>
是与I<Y, Z>
兼容的分配。
类似地,对于逆变部分,除了现在T
是固定的,并且投影会反转关系的方向。
另外,“逆变有效性逆转变异有效性的方向”是什么意思?
我的意思是,如果您阅读协变有效性的规则并将它们与协变有效性的规则进行比较,您会发现这些规则基本上是相同的,只是有一堆规则“向后翻转”。这就是为什么我们称其为“相反”方差。
我的博客上有十几篇有关差异的文章;如果您对此主题感兴趣,则可能需要从头开始阅读它们。
关于c# - 类型差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16226831/