在 CLR via c# 第三版中,有一个我似乎无法理解的示例:
不变意味着不能更改该泛型类型参数。到目前为止,我在本章中只展示了不变的泛型类型参数。n
逆变意味着泛型类型参数可以从一个类更改为从它派生的类。在 C# 中,您使用in 关键字指示逆变泛型类型参数。
逆变泛型类型参数只能出现在输入位置,例如方法的参数。n 协变意味着泛型类型参数可以从一个类更改为其基类之一。在 C# 中,您使用out 关键字指示协变泛型类型参数。协变泛型类型参数只能出现在输出位置,例如方法的返回类型。
然后作者继续举这个例子:
public delegate TResult Func<in T, out TResult>(T arg);
这里,泛型类型参数 T 用 in 关键字标记,使其具有逆变性;并且泛型类型参数 TResult 用 out 关键字标记,使其成为协变的
这是我在下一页(292)上遇到问题的地方,然后他在使用界面时说相反。
当使用接受泛型参数和返回值的委托时,建议始终为逆变和协变指定 in 和 out 关键字,因为这样做不会产生不良影响,并使您的委托可以在更多场景中使用。与委托一样,具有泛型类型参数的接口可以使其类型参数是逆变的或协变的。下面是一个带有逆变 >generic 类型参数的接口示例:
public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}
由于 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" });
在第二个示例中,他使用了 out 关键字 ( IEnumerator<out T>
),然后将其称为逆变。这是正确的还是我错过了什么。在接口中定义逆变和协变是否有区别?关于这本书,我去过 Oreilly 的网站,但没有列出。