【问题标题】:Contra- and Co-variance - CLR via C#反方差和协方差 - 通过 C# 的 CLR
【发布时间】:2011-03-21 01:45:24
【问题描述】:

在 CLR 第三版中,有一个我似乎无法理解的示例:

Invariant 表示泛型的意思 类型参数不能更改。一世 只显示了不变的泛型类型 本章到目前为止的参数。 n

Contravariant 意味着泛型 类型参数可以从一个类中改变 到从它派生的类。在 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&lt;out T&gt;),然后将其称为逆变。这是正确的还是我错过了什么。在接口中定义逆变和协变是否有区别? I have been to Oreilly's website regarding this book and this is not listed.

【问题讨论】:

  • 需要注意的是,Delegate.Combine 的设计与方差根本不兼容。如果例程有一个委托类型为Action&lt;Cat&gt; 的初始空字段,并且它尝试使用Action&lt;Animal&gt; 对其进行Combine,则Action&lt;Cat&gt; 类型的字段将包含对Action&lt;Animal&gt; 的引用。如果然后尝试使用Action&lt;Cat&gt;Combine,则尝试将失败。因此,可能与Combine 一起使用的委托类型不应是协变或逆变的。太糟糕了,委托类型没有定义自己的 Combine 方法,因为......
  • ...方法 Action&lt;Cat&gt;.Combine 可以安全地获取 Action&lt;Animal&gt; 并将其转换为类型 Action&lt;Cat&gt;,因为知道这种转换的结果只会被以下代码使用给它一个Cat

标签: .net covariance contravariance


【解决方案1】:

out = 协变in = 逆变

任何相反的词都是我书中的错误,我会在以后的版本中更正。

【讨论】:

  • 你知道你刚刚签入了加利福尼亚酒店的开发者版本,对吧?
  • 冰上的粉红香槟,有人吗?
  • 只是为了表明你不能根据他们的声誉来判断用户!
【解决方案2】:

这是一个错误。这绝对是协方差的一个例子。委托和接口之间的协变和逆变的含义没有区别。

我建议你给 O'Reilly 发邮件报告错误。

【讨论】:

  • 或者作者直接过来回答...:)
  • @Justin:嗯,是的,这总是一种选择;)
猜你喜欢
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 1970-01-01
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多