我试图找出这些词的确切含义Covariance
和Contravariance
在线和问题的几篇文章在计算器上,从我能理解,这只是为多态性另一个词 。
难道我上面的说法正确吗? 还是我听错了?
我试图找出这些词的确切含义Covariance
和Contravariance
在线和问题的几篇文章在计算器上,从我能理解,这只是为多态性另一个词 。
难道我上面的说法正确吗? 还是我听错了?
这当然涉及到多态。 我不会说他们只是“另一种说法”的多态性,但-他们的很具体的情况,在那里你可以把一个类型,就好像它是在一定的语境另一种类型。
例如,对于正常的多态,你可以把到任何引用Banana
作为一个参考Fruit
-但是,这并不意味着你可以代替Fruit
每次你看到的类型时Banana
。 例如,一个List<Banana>
不能被视为List<Fruit>
因为list.Add(new Apple())
是有效的List<Fruit>
但不为List<Banana>
。
协方差允许“更大”(较不具体的)类型,其中原始类型仅在“输出”位置中使用的API中被取代(例如作为返回值)。 逆变允许“较小”(更具体的)类型,其中原始类型仅在“输入”的位置中使用的API中被取代。
这是很难进入的一个SO后的所有细节(虽然希望别人会做得比这更好的工作!)。 埃里克利珀具有优良的系列博客文章了。
感谢所有的喊话,伙计们。
乔恩和拉斯穆斯的回答都很好,我想补充一个快速的技术说明。
当随便和非正式地说,是的,人们用“方差”和“逆变”是指一种特定的多态性。 也就是说,当你把蜘蛛的序列,就好像是动物的序列中的多态。
即便我们能够得到所有计算机sciency,努力使更多的技术定义,那么我可能不会说,协方差和逆变是“一种多态性”。 我将接近这样的更多的技术定义:
首先,我要注意,在C#两种可能的多态性,你可能会说什么,而不是迷惑他们是很重要的。
第一类是传统上被称为“特设多态”,而这也正是你有一个方法M(动物X)多态性,并且你通过蜘蛛和长颈鹿,袋鼠它,方法统一对待自己的传入参数相同通过使用由动物基类保证的共性方式。
第二类是传统上被称为“参数多态”,或“通用多态性”。 这是使一个通用方法的能力M<T>(T t)
,然后将该再有一堆在所述方法中的代码,把均匀地基于通过对T中的约束保证共性参数
我想你在谈论的第一种多态性。 但我的观点就是这样,我们可以定义多态性作为一种编程语言的处理均匀根据已知的共性不同事物的能力。 (例如,已知的基类型,或已知的实现的接口)。
协变和逆变是一种编程语言, 采取从他们的类型参数称为共性推断泛型类型之间的共性优势的能力。
你可以考虑一下合作和逆变为多态性的一种高级形式。 您不仅可以使用一个子级,如果它是它的父级,与合作和逆变,多态性延伸到涉及多态类的类。
想象一下,两个类:
public class Pet { /*...*/ }
public class Cat:Pet { /*...*/ }
多态性是能够用Cat
作为Pet
:
void Feed(Pet pet) { /* ... */ }
Cat cat = ...
Feed(cat);
CO-和逆变用于谈论能够使用一个ICollection<Cat>
作为ICollection<Pet>
(协方差):
void FeedAll(ICollection<Pet> pets) { /* ... */ }
List<Cat> cats = ...
FeedAll(cats);
或使用一个Action<Pet>
作为Action<Cat>
(逆变):
Action<Pet> GetFeeder() { /* ... */ }
Action<Cat> feeder = GetFeeder();
埃里克利珀写了一篇精彩的博客一系列关于它,当他们第一次设计特点。 第一部分是在这里 。
我发现这个集合:
协变和逆变在C#中,第一部分
协变和逆变在C#中,两个部分:数组协变
协变和逆变在C#中,第三部分:会员组转换差异
协变和逆变在C#中,第四部分:真正代表方差
协变和逆变在C#中,第五部分:高阶函数伤害了我的大脑
协变和逆变在C#中,第六部分:接口方差
协变和逆变在C#中第七部分:为什么我们需要一个语法呢?
协变和逆变在C#中,八部分:语法选项
协变和逆变在C#中,九部分:重大更改
协变和逆变在C#中,部分十:处理歧义
协变和逆变,第十一部分:为无穷大,但不超过
我认为是特殊的多态性的不是它的另一个字。 这是多态性的代表在那里与基地的返回类型的委托可以接受孩子的类型。