逆变和协方差 - 通过 C# 的 CLR

发布于 2024-09-11 02:35:58 字数 1562 浏览 4 评论 0原文

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

不变的意思是泛型 类型参数无法更改。我 仅显示不变的泛型类型 本章到目前为止的参数。

逆变的意思是泛型 类型参数可以从类中更改 到从它派生的类。在 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),然后将其称为逆变。这是正确的还是我错过了什么。定义逆变和逆变有区别吗?接口中的协变? 我去过 Oreilly 的网站了解这本书,但未列出。

In the CLR via c# third edition there is an example that I cant seem to make sense of:

Invariant Meaning that that generic
type parameter cannot be changed. I
have shown only invariant generic type
parameters so far in this chapter. n

Contravariant Meaning that the generic
type parameter can change from a class
to a class derived from it. In C#, you
indicate contravariant generic type
parameters with the in keyword.

Contravariant generic type parameters
can appear only in input positions
such as a method’s argument. n
Covariant Meaning that the generic
type argument can change from a class
to one of its base classes. In C#, you
indicate covariant generic type
parameters with the out keyword.
Covariant generic type parameters can
appear only in output positions such
as a method’s return type.

The author then goes on to give this example:

public delegate TResult Func<in T, out TResult>(T arg);

Here, the generic type parameter T is
marked with the in keyword, making it
contravariant; and the generic type
parameter TResult is marked with the
out keyword, making it covariant

Here is where I run into the issue on the following page(292) he then goes on the say the opposite when using an interface.

When using delegates that take generic arguments and return values, it is recommended to
always specify the in and out keywords for contravariance and covariance whenever >possible,
as doing this has no ill effects and enables your delegate to be used in more scenarios.
Like delegates, an interface with generic type parameters can have its type parameters be
contravariant or covariant. Here is an example of an interface with a contravariant >generic
type parameter:

public interface IEnumerator<out T> : IEnumerator {
Boolean MoveNext();
T Current { get; }
}

Since T is contravariant, it is possible to have the following code compile and run >successfully:

// 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" });

In the second example he uses the out key word (IEnumerator<out T>) and then calls it contravariant. Is this correct or am I missing something. Is there a difference defining a contravariant & covariant in an interface? I have been to Oreilly's website regarding this book and this is not listed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

行至春深 2024-09-18 02:35:58

out = 协变in = 逆变

任何与此相反的词语都是我书中的一个错误,我将在以后的版本中予以纠正。

out = covariant and in = contravariant.

Any words to the opposite are a mistake in my book which I'll correct in a future edition.

ˉ厌 2024-09-18 02:35:58

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

我建议您向 O'Reilly 发送电子邮件以报告错误。

That's a mistake. It's definitely an example of covariance. There's no difference in meaning of covariance and contravariance between delegates and interfaces.

I suggest you email O'Reilly to report the error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文