当前位置: 首页 > 编程语言 > C#

为什么接口类型列表不能接受继承接口的实例?分享

时间:2023-04-10 16:06:25 C#

为什么接口类型列表不能接受继承接口的实例?给定以下类型:publicinterfaceIPrimary{voiddoBattle();}//一个ISecondary“是”一个IPrimarypublicinterfaceISecondary:IPrimary{}//ISecondary的实现也是一个IPrimary:internalclassSecondaryImpl:ISecondary{//必需的,因为这是一个IPrimarypublicvoiddoBattle(){}我为什么不这样做?列表列表=新列表();这会导致以下编译错误:Argumenttype'System.Collections.Generic.List'isnotassignabletoargumenttype'System.Collections.Generic.List'我理解错了,我意识到有一些解决方法。我只是看不出有任何明确的理由不允许这种直接转换。毕竟ISecondary列表中包含的值应该是(推而广之)IPrimary类型的值。为什么List和List被解释为不相关的类型?谁能说清楚为什么C#是这样设计的?一个稍微扩展的示例:我在尝试执行类似以下操作时遇到了这个问题:internalclassProgram{privatestaticvoidMain(string[]args){//ISecondary的实例,以及IPrimary的实例:varmySecondaryInstance=newSecondaryImpl();//这按预期工作:AcceptImpl(mySecondaryInstance);//ISecondary的实例列表,//通过扩展,它们也是IPrimary的实例:varmyListOfSecondaries=newList{mySecondaryInstance};//但是,这不起作用(导致编译错误):AcceptList(myListOfSecondaries);}//注意:IPrimary参数:publicstaticvoidAcceptImpl(IPrimaryinstance){}//注意:IPrimary类型的列表:publicstaticvoidAcceptList(Listlist){}}我为什么不这样做呢?列表列表=新列表();假设您有一个这样定义的方法:publicvoidPopulateList(ListlistToPopulate){listToPopulate.Add(newPrimary());//Primary没有实现ISecondary!如果将List作为参数传递给它会怎样?ListcannotbeassignedfromList的错误是编译器一种让你摆脱这些麻烦的方法publicclassAnimal{...}publicclassCat:Animal{publicvoidMeow(){...}}Listcats=newList();cats.Add(新猫());猫[0].喵喵();//美好的。列出动物=猫;//假装编译。动物。添加(新动物());//同时添加一个Animal到cats列表中,因为animals引用了cats。猫[1].喵喵();//cats[1]是一个Animal,所以它爆炸了!这就是为什么。邪恶类:IPrimary{...}list.Add(newEvil());//有效的c#,但不会工作,它可以保护您免受bug的侵害。列表实例(对象)需要辅助实例。并非每个主要都是次要的。然而,预期主列表可以容纳任何主列表。如果我们可以将次要列表视为主要列表:坏事。实际上,数组确实允许这样做——如果你弄错了,你会在运行时得到一个错误。List类型在其泛型参数中不协变的原因是List不是List的子类型,因为它们是可读写的。在您的扩展示例中,您的方法AcceptList可以执行list.Add(x),其中x是IPrimary但不是ISecondary。请注意,IEnumerable是正确协变的,而数组是同类型的(您可以执行上面尝试的操作),但出于同样的原因,这是不合理的——将元素添加到集合中将在运行时失败。以上是C#学习教程:接口类型列表为什么不能接受继承接口的实例?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢