协方差是否全部与接受值有关?
我正在通过通过C#的CLR书学习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
派生的,所以是协变的,但不是协变的),它用于传递参数(但不返回值)的上下文中。
因此,在上面的示例中,我们应该使用协变而不是协变(这意味着书中有错误)吗?
UPDATE
发表评论后,我又提出了一个问题。以下定义正确吗?
Contravariant意味着泛型类型参数可以从一个类更改为一个类从中得出。在C#中,您可以使用in关键字指示互变的泛型类型参数。相反的泛型类型参数只能出现在输入位置,例如方法的论点。
Covariant意味着泛型类型参数可以从类更改为其基类之一类。在C#中,您可以使用out关键字指示协变泛型类型参数。协变
正如乔希指出,这本书是正确的。
如果您想从其他来源确认this link,则可以检查。
IEnumerable<Cat>
是IEnumerable<Animal>
的子类型。保留子类型,因为IEnumerable<T>
与T
协变。
C#中用于这些概念的两个关键字是out
表示协变,in
表示协变。在IEnumerable<T>
情况下,它转换为IEnumerable<out T>
。
希望这会有所帮助。
UPDATE
您将必须按如下方式颠倒定义。
Covariant意味着通用类型参数可以从一个类更改为从其派生的类(
IEnumerable<Object>
至IEnumerable<String>
)。在C#中,您可以使用out关键字指示协变泛型类型参数。Contravariant表示通用类型参数可以从类为其基类之一。在C#中,您指示反变具有in关键字的通用类型参数。