对比和协方差 - CLR通过C#

Chr*_*s G 5 .net covariance contravariance

在CLR中通过c#第三版有一个我似乎无法理解的例子:

不变意味着无法更改泛型类型参数.到目前为止,我在本章中只显示了不变的泛型类型参数.ñ

Contravariant意味着泛型类型参数可以从类更改为从它派生的类.在C#中,使用in关键字指示逆变泛型类型参数.

逆变泛型类型参数只能出现在输入位置,例如方法的参数.n Covariant意味着泛型类型参数可以从类更改为其基类之一.在C#中,您使用out关键字指示协变泛型类型参数.协变泛型类型参数只能出现在输出位置,例如方法的返回类型.

然后作者继续给出这个例子:

public delegate TResult Func<in T, out TResult>(T arg);
Run Code Online (Sandbox Code Playgroud)

这里,泛型类型参数T用in关键字标记,使其成为逆变; 并且泛型类型参数TResult用out关键字标记,使其协变

这是我在下一页(292)遇到问题的地方,然后他继续使用界面说相反.

当使用带有泛型参数和返回值的委托时,建议在任何可能的情况下始终为逆变和协方差指定输入和输出关键字,因为这样做没有任何不良影响,并使您的委托可以在更多场景中使用.与委托一样,具有泛型类型参数的接口可以使其类型参数具有逆变性或协变性.以下是具有逆变>泛型类型参数的接口示例:

public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}
Run Code Online (Sandbox Code Playgroud)

由于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" });
Run Code Online (Sandbox Code Playgroud)

在第二个例子中,他使用out关键字(IEnumerator<out T>)然后将其称为逆变量.这是正确的还是我错过了什么.在界面中定义逆变和协变是否有区别?我去过Oreilly的网站关于这本书,但没有列出.

小智 20

out= 协变in= 逆变.

任何相反的话都是我书中的错误,我将在未来的版本中纠正.

  • 你知道你刚刚进入加利福尼亚酒店的开发者版本,对吧? (9认同)

Jon*_*eet 9

那是个错误.这绝对是协方差的一个例子.代表和接口之间协方差和逆变的含义没有区别.

我建议您通过电子邮件向O'Reilly报告错误.