C# 中的协变/逆变

发布于 2024-11-25 11:40:43 字数 1024 浏览 2 评论 0 原文

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

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

,这是一个例子。

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

我认为为了使用协变/逆变,需要使用 new 如示例中所示,但我似乎使用 sa = ActionObject 和 <代码>o = 检索字符串。 (我用 Mono 测试过)。

  • 那么,为什么作者用new来解释协变/逆变呢?
  • 协变/逆变思想背后的理论是什么?它只是一个描述对象x=一切都继承自对象的奇特名称吗?这个奇怪的名字从何而来?它的用途是什么?

I have a book that explains contravariance/covariance as follows :

  • a delegate can have more specific parameter types than its method target. This is called contravariance
  • the return type of a delegate can be less specific than the return type of its target method. This is called covariance

And, this is an example.

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

I thought in order to use covariance/contravariance, one needs to use new as is shown in the example, but I seem to get the same result with sa = ActionObject and o = RetrieveString. (I tested with Mono).

  • Then, why the writer uses new to explain covariance/contravariance?
  • What's the theory behind the covariance/contravariance idea? Is it just a fancy name describing object x = Everything inherit from object? Where is this weird name come from? What's the usage for it?

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

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

发布评论

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

评论(4

酸甜透明夹心 2024-12-02 11:40:43

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

这不是对方差的一个很好的解释。人们完全不清楚所谓的“协方差”和“逆变”到底是什么。

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

尝试阅读此内容,看看您是否能更好地理解它:

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

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

从 C# 2.0 开始,您可以说“d = M”或“d = new D(M)”——编译器只是将它们识别为编写同一事物的两种不同方式。

为什么作者用 new 来解释协变/逆变?

我不知道。

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

理论是,如果你有一个排序关系——也就是说,如果X x = (Y)y是合法的,那么X比Y大——并且你有一个映射保留排序关系,则映射是协变的。如果它颠倒顺序关系,则它是逆变

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

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

您可以将方法 M-that-takes-an-Animal 分配给类型为 D-that-takes-a-Giraffe 的变量。 D(长颈鹿)> M(动物)但动物>长颈鹿。关系颠倒了映射逆变

这只是一个描述对象 x = 一切都继承自对象的奇特名称吗?

不。它与该概念相关,因为对象是一种比几乎所有其他类型都大的类型。但实际上变体是保留或反转大小关系的映射

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

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

这个奇怪的名字从何而来?

范畴论。

I have a book that explains contravariance/covariance as follows ...

That is not a very good explanation of variance. It is left completely unclear precisely what it is that is called "covariance" and "contravariance".

The thing that actually is variant is never mentioned. The thing that is contravariant is the mapping from a type to a delegate with a parameter of that type. Contravariance is a property of mappings and relationships.

Try reading this and see if you understand it any better:

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

I thought in order to use covariance/contravariance, one need to use new as is shown in the example, but I seem to get the same result ...

Ever since C# 2.0 you can say either "d = M" or "d = new D(M)" -- the compiler simply recognizes them as two different ways to write the same thing.

why the writer uses new to explain covariance/contravariance?

I don't know.

What's the theory behind the covariance/contravariance idea?

The theory is that if you have an ordering relationship -- that is, X is bigger than Y if it is legal to say X x = (Y)y -- and you have a mapping that preserves the ordering relationship, then the mapping is covariant. If it reverses the ordering relationship, it is contravariant.

For example, suppose Animal is a bigger type than Giraffe. So you can assign an object of type Giraffe to a variable of type Animal. Animal > Giraffe.

Now make a mapping from a type T to a method M-that-takes-a-T and to a delegate type D-that-takes-a-T.

You can assign a method M-that-takes-an-Animal to a variable of type D-that-takes-a-Giraffe. D(Giraffe) > M(Animal) but Animal > Giraffe. The relationship is reversed; the mapping is contravariant.

Is it just a fancy name describing object x = Everything inherit from object?

No. It is related to that concept because object is a larger type than almost every other type. But what is actually variant is a mapping that preserves or reverses a size relationship.

Try reading this and see if it helps.

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

Where is this weird name come from?

Category theory.

花落人断肠 2024-12-02 11:40:43

我见过的描述 C# 中协变/逆变的最佳信息是 Eric Lippert 的一系列博客文章 此处。请参阅从列表底部开始的十一部分系列。

有时读起来有点困难。但它解释了你一开始可能问的所有问题。 :)

它是在实际的 C# 4.0 实现之前编写的,因此一些语法讨论已经过时,但其他所有内容似乎都按照描述的方式实现。

The best info describing covariance/contravariance in the C# I've ever seen is series of blog posts by Eric Lippert here. See starting from the bottom of the list, eleven-parts series.

It is somewhat hard to read sometimes. But it explains everything you could ask in the beginning. :)

It was written prior to actual C# 4.0 implementation, so some discussion of the syntax is obsolete, but everything else seems to be implemented just as described.

我一直都在从未离去 2024-12-02 11:40:43

这里有一篇很棒的 wiki 文章:这里

漏斗倾倒并将漏斗的宽度设置在适当的水平......

Here's a great wiki article on it: here

It's more a matter of which direction the funnel pours and setting the width of the funnel at an appropriate level...

梦境 2024-12-02 11:40:43

不知道你第一个问题的意思。

第二个问题可以通过建议考虑选角来回答。逆变允许具有扩展类 B 的类 A 存储为类 B。

逆变

class A {
}

class B : public A {
}

B obj = new A();

允许扩展类 A 但存储为类 A 的类 B。

协方差

class A {
}

class B : public A {
}

A obj = new B();

No idea what you mean in your first question.

The second question can be answered by suggesting looking at casting. Contravariance is allowing class A which has an extended class B be stored as a class B.

Contravariance

class A {
}

class B : public A {
}

B obj = new A();

Covariance is allowing class B which extends class A but stored as a class A.

Covariance

class A {
}

class B : public A {
}

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