在C#4.0泛型方差 [英] Generic Variance in C# 4.0

查看:224
本文介绍了在C#4.0泛型方差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一般差异在C#4.0已经以这样的方式来实现,它可以编写以下无异常(这是在C#中会发生什么3.0):

Generic Variance in C# 4.0 has been implemented in such a way that it's possible to write the following without an exception (which is what would happen in C# 3.0):

 List<int> intList = new List<int>();
 List<object> objectList = intList; 

【例非功能性:参见乔恩斯基特的答案]

[Example non-functional: See Jon Skeet's answer]

我最近参加了一个会议,其中乔恩斯基特给通用差异的一个很好的概述,但我不知道我完全得到它 - 我理解的的意义退出键的话,当谈到禁忌和共同方差,但我很好奇,在幕后发生的事情。

I recently attended a conference where Jon Skeet gave an excellent overview of Generic Variance, but I'm not sure I'm completely getting it - I understand the significance of the in and out key words when it comes to contra and co-variance, but I'm curious to what happens behind the scenes.

什么CLR的看到,当这code执行是它隐含转换名单,其中; INT&GT; 名单,其中,对象&gt; 或者它只是内置的,我们现在可以派生类型之间进行转换,以父类型

What does the CLR see when this code is executed? Is it implicitly converting the List<int> to List<object> or is it simply built in that we can now convert between derived types to parent types?

出于兴趣,为什么不这样介绍了previous版本,什么是主要的好处 - 即现实世界中使用

更多信息<一个href="http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-4-0">post对于通用方差(但问题是非常过时,寻找真正的,最新的最新信息)

More info on this post for Generic Variance (but question is extremely outdated, looking for real, up-to-date information)

推荐答案

没有,你的榜样也不会,原因有三工作:

No, your example wouldn't work for three reasons:

  • 类(如名单,其中,T&GT; )是不变的;只有代表和接口都变
  • 方差工作,接口只使用类型参数在一个方向(为逆变,出来的协方差)
  • 在值类型不支持类型参数的变化 - 因此没有从的IEnumerable&LT converstion; INT&GT; 的IEnumerable&LT;对象&gt; 例如
  • Classes (such as List<T>) are invariant; only delegates and interfaces are variant
  • For variance to work, the interface has to only use the type parameter in one direction (in for contravariance, out for covariance)
  • Value types aren't supported as type arguments for variance - so there's no converstion from IEnumerable<int> to IEnumerable<object> for example

(将code编译失败在C#3.0和4.0 - 没有例外)

(The code fails to compile in both C# 3.0 and 4.0 - there's no exception.)

所以这个的的工作:

IEnumerable<string> strings = new List<string>();
IEnumerable<object> objects = strings;

在CLR只是使用参考,不变的 - 没有创建新的对象。所以,如果你叫 objects.GetType()你还能名单,其中,串&GT;

我相信这不是前面介绍,因为语言设计者仍然必须制定出如何暴露的细节 - 它一直以来V2的CLR

I believe it wasn't introduced earlier because the language designers still had to work out the details of how to expose it - it's been in the CLR since v2.

的好处是相同的要在其中能够使用一种类型作为另一个其它时间。要使用相同的例子,我用最后一个星期六,如果你已经得到的东西器具的IComparer&LT;形状&GT; 按面积来比较的形状,它的疯狂,你不能用它来排序名单,其中,圈&GT; - 如果它可以比较任意两个形状,它当然可以比较任意两个圆圈。由于C#4,会从的IComparer℃的逆变转换;形状&GT; 的IComparer&LT;圈&GT; 所以你可以调用 circles.Sort(areaComparer)

The benefits are the same as other times where you want to be able to use one type as another. To use the same example I used last Saturday, if you've got something implements IComparer<Shape> to compare shapes by area, it's crazy that you can't use that to sort a List<Circle> - if it can compare any two shapes, it can certainly compare any two circles. As of C# 4, there'd be a contravariant conversion from IComparer<Shape> to IComparer<Circle> so you could call circles.Sort(areaComparer).

这篇关于在C#4.0泛型方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆