C#中的协方差/逆变

pro*_*eek 7 c# covariance contravariance

我有一解释逆变/协方差的如下:

  • 委托可以具有比其方法目标更具体的参数类型.这称为逆变
  • 委托的返回类型可以比其目标方法的返回类型更不具体.这称为协方差

而且,这是一个例子.

using System;

delegate void StringAction(string s);
delegate object ObjectRetriever();

class Test
{
    static void Main()
    {
        StringAction sa = new StringAction(ActionObject);
        sa("hello");

        ObjectRetriever o = new ObjectRetriever(RetrieveString);
        object result = o();
        Console.WriteLine(result);
    }


    static string RetrieveString() {return "hello";}

    static void ActionObject(object o)
    {
        Console.WriteLine(o);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为为了使用协方差/逆变,需要使用new如示例中所示,但我似乎得到了相同的结果sa = ActionObjecto = RetrieveString.(我用Mono测试过).

  • 那么,为什么作者new用来解释协方差/逆变?
  • 协方差/逆变思想背后的理论是什么?它只是一个花哨的名字描述object x = Everything inherit from object?这个奇怪的名字来自哪里?它的用途是什么?

Eri*_*ert 18

我有一本书解释了逆变/协方差如下......

这不是对方差的非常好的解释.完全不清楚被称为"协方差"和"逆变"是什么.

从未提及实际上是变体的东西.逆变的是从类型到具有该类型参数的委托的映射.逆变性是映射关系的属性.

试着阅读本文,看看你是否更了解它:

http://blogs.msdn.com/b/ericlippert/archive/2007/10/19/covariance-and-contravariance-in-c-part-three-member-group-conversion-variance.aspx

我想为了使用协方差/逆变,需要使用新的,如示例中所示,但我似乎得到相同的结果......

从C#2.0开始,您可以说"d = M"或"d = new D(M)" - 编译器只是将它们识别为两种不同的方式来编写相同的东西.

为什么作者用新来解释协方差/逆变?

我不知道.

协方差/逆变思想背后的理论是什么?

该理论是,如果你有一个排序的关系-也就是说,x比y大,如果它是合法的,说X X =(Y)Y -和你有一个映射的是保持顺序关系,那么映射协变.如果它颠倒了排序关系,则它是逆变的.

例如,假设Animal比Giraffe更大.因此,您可以将类型为Giraffe的对象分配给Animal类型的变量.动物>长颈鹿.

现在进行从类型T到方法M-that-take-aT和委托类型D-that-take-aT的映射.

您可以将一个方法M-that-take-an-Animal分配给D-that-takes-a-Giraffe类型的变量.D(长颈鹿)> M(动物)但动物>长颈鹿.这种关系是相反的 ; 该映射逆变.

它只是一个描述对象的奇特名称x = Everything从对象继承吗?

不.它该概念有关,因为对象比几乎所有其他类型都要.但实际变化的是保留或逆转大小关系的映射.

尝试阅读本文,看看它是否有帮助.

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

这个奇怪的名字来自哪里?

分类理论.