3

来自维基百科

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

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

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

有了这两个与代表有关的定义,它们不应该都是协变的吗?在这两种情况下,委托都期望“更宽”的类型,但被赋予“更窄的类型”。

请参阅此处以获取来自 MSDN 的两者的示例。

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

4

2 回答 2

3

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

最后一段简要概述了分配兼容性。

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

于 2011-03-08T18:47:51.767 回答
2

我现在不同意 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中快速通道代表章节的协变和逆变部分以及上面引用引文的链接的结果。

于 2011-03-14T22:02:28.110 回答