C#规范指出参数类型不能同时是协变和逆变的。这在创建协变或逆变接口(interface)时很明显,您分别用“out”或“in”修饰类型参数。没有同时允许两者的选项(“outin”)。这种限制仅仅是一种特定于语言的约束,还是基于范畴论的更深层、更根本的原因会让您不希望您的类型既是协变又是逆变的?编辑:我的理解是数组实际上是协变和逆变的。publicclassPet{}publicclassCat:Pet{}publicclassSiamese:Cat{}Cat[]cats=newCat[10];Pet[]pets=newPet[10];Siamese[]siameseCats=newSi
这是CLR的限制还是与现有代码存在兼容性问题?这是否与C#4.0中委托(delegate)组合的困惑变化有关?编辑:是否有可能在CLR上运行没有这种限制的使用协变/逆变的语言? 最佳答案 您会想阅读埃里克·利珀特(EricLippert)的博文,了解它为何如此运作。简而言之,他们允许尽可能多的变化,不允许开发人员在编程中犯下可能导致难以追踪错误的严重错误。4.0中的差异量比3.0规则大大扩展,据我所知,这是对开发人员有益的内容与允许安全的内容之间的平衡,不会因无意的错误引起太多麻烦。http://blogs.msdn.com/b/e
更新:以下代码仅在C#4.0(VisualStudio2010)中有意义看来我对协变/逆变有一些误解。谁能告诉我为什么以下代码无法编译?publicclassTestOne{publicIEnumerableMethod(IEnumerablevalues)whereTDerived:TBase{returnvalues;}}编译时:(!!!)publicinterfaceIBase{}publicinterfaceIDerived:IBase{}publicclassTestTwo{publicIEnumerableMethod(IEnumerablevalues){returnva
我被thisSOquestion触发了关于Autofac的(.NET4.0)协变和逆变支持,现在我正在尝试实现类似的东西,但没有任何运气。我想要实现的是以这样的方式配置Autofac,当我解析一个具体的IEventHandler时(为了使用container.Resolve进行演示,但通常当然使用构造函数注入(inject)),Autofac将返回一个MultipleDispatchEventHandler它包装了所有可从请求的处理程序分配的已注册事件处理程序。换句话说,当我这样写的时候:varhandler=container.GetInstance>();handler.Handl
给定以下类型:publicinterfaceIMyClass{}publicclassMyClass:IMyClass{}我想知道如何转换List到List?我对协变/逆变主题不是很清楚,但我知道我不能因此而简单地使用List。我只能想出这个微不足道的解决方案;缺乏优雅,浪费资源:...publicListConvertItems(Listinput){varresult=newList(input.Count);foreach(varitemininput){result.Add(item);}returnresult;}....如何以更优雅/更高效的方式解决它?(请注意,我需要.N
此代码段未在LINQPad中编译。voidMain(){(new[]{0,1,2,3}).Where(IsNull).Dump();}staticboolIsNull(objectarg){returnarg==null;}编译器的错误信息是:Nooverloadfor'UserQuery.IsNull(object)'matchesdelegate'System.Func'它适用于字符串数组,但不适用于int[]。这显然与拳击有关,但我想知道详细信息。 最佳答案 给出的答案(值类型不存在差异)是正确的。当可变类型参数之一是值类型时
C#4.0将支持协变和逆变。但是我并不清楚这个新特性的好处。你能(清楚地)解释一下我们为什么需要它吗? 最佳答案 它们只允许您做一些概念上有效且形式上可接受的事情,但由于语言限制目前不允许这样做。例如:IEnumerableints=newList{1,2,3};Action>PrintThings=x=>{foreach(varthinginx)Console.WriteLine(thing);};PrintThings(ints);//doesn'tcompilerightnow:(willcompilein4.0没有根本原因说
例如IEnumerable界面:publicinterfaceIEnumerable:IEnumerable{IEnumeratorGetEnumerator();}在此接口(interface)中,泛型仅用作接口(interface)方法的返回类型,不用作方法参数的类型,因此它可以是协变的。鉴于此,编译器理论上不能从接口(interface)中推断出差异吗?如果可以,为什么C#要求我们显式设置co/contravariance关键字。更新:正如JonSkeet提到的,这个问题可以分解为子问题:编译器能否通过在当前泛型类型及其所有基类型中使用泛型类型来推断泛型类型的协变/逆变?例如..
这个问题在这里已经有了答案: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
我在外部类中有以下方法publicstaticvoidDoStuffWithAnimals(IDictionaryanimals)在我的调用代码中,我已经有一个Dictionary对象,但我不能将其作为此方法的参数传递。所以一个IDictionary不是逆变的吗?我看不出为什么这不起作用。我能想到的唯一解决办法是:varanimals=newDictionary();foreach(varkvpinlions){animals.Add(kvp.Key,kvp.Value);}有没有办法将这个字典传递给这个方法,而不必创建相同对象的新字典?编辑:因为这是我的方法,我知道我从字典中使用的唯