草庐IT

c# - 协变和逆变有什么好处?

C#4.0将支持协变和逆变。但是我并不清楚这个新特性的好处。你能(清楚地)解释一下我们为什么需要它吗? 最佳答案 它们只允许您做一些概念上有效且形式上可接受的事情,但由于语言限制目前不允许这样做。例如:IEnumerableints=newList{1,2,3};Action>PrintThings=x=>{foreach(varthinginx)Console.WriteLine(thing);};PrintThings(ints);//doesn'tcompilerightnow:(willcompilein4.0没有根本原因说

c# - 在 C# 4.0 中,为什么方法中的输出参数不能协变?

鉴于这个神奇的界面:publicinterfaceIHat{TRabbitTake();}这个类的层次结构:publicclassRabbit{}publicclassWhiteRabbit:Rabbit{}我现在可以编译了:IHathat1=null;IHathat2=hat1;太棒了。但是,如果我以不同的方式定义接口(interface)会怎样:publicinterfaceIHat{boolTake(outTRabbitr);}我表示帽子可能是空的,使用单独的bool返回值(以前的版本可能会从空帽子返回nullrabbit)。但我仍然只输出一只兔子,所以没有做任何逻辑上与以前版本

c# - 为什么通用接口(interface)在默认情况下不是协变/逆变的?

例如IEnumerable界面:publicinterfaceIEnumerable:IEnumerable{IEnumeratorGetEnumerator();}在此接口(interface)中,泛型仅用作接口(interface)方法的返回类型,不用作方法参数的类型,因此它可以是协变的。鉴于此,编译器理论上不能从接口(interface)中推断出差异吗?如果可以,为什么C#要求我们显式设置co/contravariance关键字。更新:正如JonSkeet提到的,这个问题可以分解为子问题:编译器能否通过在当前泛型类型及其所有基类型中使用泛型类型来推断泛型类型的协变/逆变?例如..

c# - 通用协变和逆变

这个问题在这里已经有了答案:QuestionaboutC#covariance(4个答案)关闭9年前。考虑代码片段。IListobj=newList();IEnumerableobj1=obj;但是如果我写ICollectionobj2=obj;它抛出一个编译时错误。Cannotimplicitlyconverttype'System.Collections.Generic.IList'to'System.Collections.Generic.ICollection'.为什么自List以来出现此行为同时实现IEnumerable和ICollection还有IList定义为public

c# - 了解 C# 4.0 中的协变和逆变

我在第9channel看了一段关于它的视频,但我并没有真正理解它。有人可以给我一个简单易懂的例子吗?在那之后可能如何在实践中使用它? 最佳答案 你可能想看看这个博客,他解释得很好,但我认为需要更多的例子来为人们澄清,因为这进入了一个非常难以理解的领域,但是,文章下面的引述很好地总结了这一点。http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html"covarianceandcontravariance"me

java - Java List 在初始化期间是否表现为协变类型?

我知道Java中的列表是不变的。所以下面的第二条语句给出了预期的编译错误Listintegers=Arrays.asList(1,2,3);Listnumbers=integers;但是,所有这些都工作正常Listnumbers1=Arrays.asList(1,2,3);Listnumbers2=Arrays.asList(1,2,3);Listnumbers3=Arrays.asList(1,2,3);所以我的问题是上面最后一条语句是如何编译的?我明白Arrays.asList()接受来自其调用者的类型,但我认为Arrays.asList(1,2,3)谁会解析为最接近的类型List

java - 协变参数类型如何在 Java 中工作

鉴于Date有一个名为“after(Date)”的方法,而Timestamp有一个覆盖它的方法,名为“after(Timestamp)”,为什么Date中的after方法在下面被调用代码?关于意外结果的问题被问到here.java.sql.Timestampone=newjava.sql.Timestamp(1266873627200L);java.sql.Timestamptwo=newjava.sql.Timestamp(1266873627000L);java.util.DateoneDate=(java.util.Date)one;java.util.DatetwoDate=(

java - 如何确保仅协变地使用类型参数?

假设我有一个通用接口(interface)Source这是T的纯生产商对象。作为一个纯粹的生产者是接口(interface)契约的一部分。所以itisareasonableexpectation无论你能用Source做什么,如果你有Source也应该可以做到.现在我需要在Source的正文中强制执行此限制,这样就不会有人不小心使用了T以一种与该契约(Contract)相矛盾的方式。来自JDK的示例正如@Miserable.Variable指出的那样,ArrayList和ArrayList不等价。那是因为ArrayList作为通用类型不是协变的。或者换句话说,ArrayList不是T的纯

Java:方法参数中的协变通配符边界

我对通配符边界的规则感到困惑。好像有时候声明一个bound不满足类声明的bound的方法参数是可以的。在下面的代码中,方法foo(...)可以正常编译,但bar(...)不能。我不明白为什么允许其中任何一个。publicclassTestSomething{privatestaticclassA{}publicstaticvoidfoo(A>a){}publicstaticvoidbar(A>a){}} 最佳答案 让我们首先考虑方法voidfoo(A>a).A>与A“兼容”因为存在通配符类型P,和一个类似的通配符类型Q满足以下条件:

java - 为什么在 java 方法重写中允许具有协变返回类型,但不允许协变参数?

例如,我有一个Processor基类,其方法返回一个Object并将Object作为参数。我想扩展它并创建一个StringProcessor,它将返回String并将String作为参数。然而协变类型只允许返回值,而不是参数。这种限制的原因是什么?classProcessor{Objectprocess(Objectinput){//createacopyofinput,modifyitandreturnitreturncopy;}}classStringProcessorextendsProcessor{@OverrideStringprocess(Stringinput){//pe