【发布时间】:2019-12-30 15:29:08
【问题描述】:
协方差就是接受值吗?
我正在通过 CLR via C# 一书学习 C#。我看到以下摘录:
由于 T 是协变的,因此可以成功编译并运行以下代码:
// This method accepts an IEnumerable of any reference type
Int32 Count(IEnumerable<Object> collection) { ... }
...
// The call below passes an IEnumerable<String> to Count
Int32 c = Count(new[] { "Grant" });
我在这里很困惑。因为协方差是关于具有作为所需类型的基本类型之一的类型。因此,协方差仅在返回类型的上下文中使用。而在上面的示例中,我们有一个 String(派生自 Object,因此它是逆变的,但不是协变的),它用于传递参数(但不返回值)的上下文中。
那么,我们应该在上面的例子中使用逆变而不是协变(意思是书中有错误)?
更新
在 cmets 之后,我得到了另一个问题。以下定义正确吗?
逆变意味着泛型类型参数可以从一个类变为一个类 从中衍生出来的。在 C# 中,您使用 in 关键字指示逆变泛型类型参数。 逆变泛型类型参数只能出现在输入位置,例如方法的 论据。
协变意味着泛型类型参数可以从一个类更改为其基类之一 类。在 C# 中,您使用 out 关键字指示协变泛型类型参数。协变
【问题讨论】:
-
Covariance和contravariance启用数组类型、委托类型和泛型类型参数的隐式引用转换。Covariance保留了赋值兼容性,而逆变换了它...see more here,这不是书中的错误,而且是正确的。 -
IEnumerable<T>在T上是协变的,这本书是准确的。
标签: c# generics covariance contravariance