协方差是否都是关于接受值?

问题描述 投票:2回答:1

协方差是否全部与接受值有关?

我正在通过通过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关键字指示协变泛型类型参数。协变

c# generics covariance contravariance
1个回答
1
投票

正如乔希指出,这本书是正确的。

如果您想从其他来源确认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关键字的通用类型参数。

© www.soinside.com 2019 - 2024. All rights reserved.