【问题标题】:Variance on types类型差异
【发布时间】:2013-04-26 00:22:59
【问题描述】:

以下总结了我对 C# 中方差的理解。如果您能告诉我哪里出了问题,我将不胜感激,因为我阅读了 Eric Lippert 在 Exact rules for variance validity 上的文章,但大部分内容我都无法理解。 p>

方差是一个类型到另一种类型的转换(或 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 上逆变是什么意思?

另外,逆变效度反转变体效度方向和协变效度反转变体效度方向是什么意思?

【问题讨论】:

  • 这是一个相当复杂的问题,在这里的范围似乎有点大。老实说,我建议您阅读除 Eric 之外的更多文章,以了解协变和逆变。

标签: c# variance


【解决方案1】:

现在,一个类型是协变的还是逆变的意味着什么?方差不是类型投影的属性而不是类型本身的属性吗?

是的,你是正确的。好吧,你几乎是正确的。方差是类型相对于类型上的给定关系的投影的属性。

考虑以下陈述:

  • 从引用类型 T 映射到类型 IEnumerable<T> 的投影保留了赋值兼容性关系的方向,因此该投影是协变的 .

  • TIEnumerable<T> 的投影在 T 中是协变的。

  • IEnumerable<T>T 中是协变的。

  • IEnumerable<T> 是协变的。

我们说第四个;我们的意思是第一个。我们假设通过“IEnumerable<T> 是协变的”,从上下文中可以清楚地看出投影是什么(从 TIEnumerable<T>)以及保留的关系是什么(赋值兼容性)。那样说起来更容易。

在你提到的那篇文章中,我一开始比这更草率;我使用“协变”基本上是指“可以以某种方式参与协变转换”。但是,“协变有效”等的定义是精确的。如果称其为“协变有效”让人难以理解,请称其为其他名称:

如果类型 X 是指针、非泛型、具有 Frobby 元素类型的数组,或者其中每个“in”类型参数都是 Blobby、每个“out”类型的泛型类型,则称类型 X 为 Frobby 类型参数是 Frobby,所有其他类型参数都是 Frobby 和 Blobby。如果它是一个指针,或者非泛型,或者具有 Blobby 元素类型的数组,或者一个泛型类型,其中每个“in”类型参数都是 Frobby,每个“out”类型参数都是 Blobby,那么它就被称为 Blobby,并且每个其他类型参数是 Frobby 和 Blobby。

在那里,我们根本没有使用“协变”或“逆变”这两个词,而且我们对 Frobby 和 Blobby 都有一个精确的定义。

泛型类型I<out T, in U>T 上协变而在U 上逆变是什么意思?

同样,这只是一个简短的形式。第一部分意味着对于任何固定的U,从引用类型TI<T, U> 的投影是保留分配兼容性方向的投影。如果X 的赋值与Y 兼容并且Z 是任何类型,那么I<X, Z> 的赋值与I<Y, Z> 兼容。

对于逆变部分类似,除了现在T 是固定的,并且投影反转关系的方向。

还有,“逆变效度反转变体效度的方向”是什么意思?

我的意思是,如果您阅读协变有效性规则并将它们与逆变有效性规则进行比较,您会注意到这些规则基本相同,只是一堆规则“倒退”了。这就是为什么我们称它为 *contra*variance。

我的博客上有十几篇关于方差的文章;如果你对这个主题感兴趣,你可能想从头开始阅读。

【讨论】:

  • 弗罗比和布洛比?笑声本身就值得 +1。
  • 谢谢埃里克!您拥有如此惊人的方法,可以将高度复杂的信息转化为普通人可以理解的简化和结构化的术语和概念。
猜你喜欢
  • 2011-10-18
  • 1970-01-01
  • 2021-12-26
  • 2020-08-27
  • 1970-01-01
  • 1970-01-01
  • 2015-12-02
  • 2014-06-16
  • 2015-02-08
相关资源
最近更新 更多