从语言角度来说,逆变与代表相关的意义如何?

发布于 2024-10-21 01:27:48 字数 580 浏览 4 评论 0原文

来自维基百科

协变:从更宽(双) 变窄(浮动)。
逆变:从较窄(浮动)转换为较宽(双精度)。

在 .NET 中,委托具有协变性,因为它允许委托的指定返回类型的派生类型成为它所引用的方法的返回类型。

委托还具有逆变性,因为它允许委托的指定参数(参数)的派生类型成为传递到它所引用的方法中的参数类型。

有了这两个与委托相关的定义,它们不应该都是协方差的吗?在两种情况下,委托都期望“更宽”的类型,但得到的却是“更窄的类型”。

有关两者的示例,请参阅此处来自 MSDN。

那么,当与代表相关时,“逆变”这个词在语言上有何意义呢?

From Wikipedia:

covariant: converting from wider (double) to narrower (float).
contravariant: converting from narrower (float) to wider (double).

In .NET, a delegate has covariance because it allows for derived types of the delegate's specified return type to be the return type of a method that it holds a reference to.

As well a delegate has contravariance because it allows for derived types of the delegate's specified arguments (parameters) to be the argument type passed into the method that it holds a reference to.

With these two definitions as they pertain to delegates, shouldn't they both be covariance? In both cases, the delegate expects a "wider" type, but is given a "narrower type".

See here for an example of both from MSDN.

So how does the word contravariance make sense, linguistically, when pertaining to delegates?

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

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

发布评论

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

评论(2

小嗷兮 2024-10-28 01:27:48

http://blogs.msdn.com/b/ericlippert/archive/2009/11/30/what-s-the-difference- Between-covariance-and-assignment-compatibility.aspx

最后一段对赋值兼容性有一个简洁的总结。

//从语言上来说,这在参数与返回的意义上似乎是合乎逻辑的 - 所以 //向前或向后的方向是关于进入或离开函数。

http://blogs.msdn.com/b/ericlippert/archive/2009/11/30/what-s-the-difference-between-covariance-and-assignment-compatibility.aspx

Last paragraph has a concise summary of assignment compatibility.

//Linguistically, this seems to be logical in the sense of parameters versus return- so the direction //forward or backward is with regards to going in or coming out of the function.

颜漓半夏 2024-10-28 01:27:48

我现在不同意 SeanVDH 的回答。他说:“从语言上来说,这在参数与返回的意义上似乎是合乎逻辑的——所以前进或后退的方向是关于进入或离开函数的”。

相反,我认为这是来自 此处

协方差保留 赋值兼容性 和逆变将其反转。协方差是一种加宽转换,而逆变是一种缩小转换。

当您实例化委托时,您
可以为其分配一个具有更多的方法
派生返回类型比
在委托中指定
(协方差)。您还可以分配一个
参数类型较少的方法
比委托中的派生
(逆变)。 添加了强调

示例:

static object GetObject() { return null; }
static void SetObject(object obj) { }

static string GetString() { return ""; }
static void SetString(string str) { }

static void Main()
{
    // Covariance. A delegate specifies a return type as object,
    // but I can assign a method that returns a string.
    Func<object> del = GetString;

    // Contravariance. A delegate specifies a parameter type as string,
    // but I can assign a method that takes an object.
    Action<string> del2 = SetObject;

    // But implicit conversion between generic delegates is not supported until C# 4.0.
    Func<string> del3 = GetString;
    Func<object> del4 = del3; // Compiler error here until C# 4.0.
}

这一认识是阅读 Eric Lippert 的文章(Jon 中快速跟踪代表章节的协变和逆变部分的结果) Skeet 的书《C# In Depth》,以及上面引用的链接。

I now disagree with the answer from SeanVDH. He says "Linguistically, this seems to be logical in the sense of parameters versus return- so the direction forward or backward is with regards to going in or coming out of the function".

Instead I think this is the answer which comes from here:

Covariance preserves assignment compatibility and contravariance reverses it. Covariance is a widening conversion, and contravariance is a narrowing conversion.

When you instantiate a delegate, you
can assign it a method that has a more
derived return type than that
specified in the delegate
(covariance). You can also assign a
method that has parameter types less
derived than those in the delegate
(contravariance). Emphasis added

Example:

static object GetObject() { return null; }
static void SetObject(object obj) { }

static string GetString() { return ""; }
static void SetString(string str) { }

static void Main()
{
    // Covariance. A delegate specifies a return type as object,
    // but I can assign a method that returns a string.
    Func<object> del = GetString;

    // Contravariance. A delegate specifies a parameter type as string,
    // but I can assign a method that takes an object.
    Action<string> del2 = SetObject;

    // But implicit conversion between generic delegates is not supported until C# 4.0.
    Func<string> del3 = GetString;
    Func<object> del4 = del3; // Compiler error here until C# 4.0.
}

This realization was the result of reading Eric Lippert's article, the Covariance and contravariance section of the Fast-tracked delegates chapter in Jon Skeet's book C# In Depth, as well as the link above where the quote was drawn from.

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