条件表达式无法确定?我刚遇到这个(编写代码来演示“问题”):publicICollectionCreateCollection(intx){ICollectioncollection=x==0?新列表():新链表();退货收集;}编译器抱怨:FehlerCS0173:DerTypdesbedingtenAusdruckskannnichtbestimmtwerden,weilkeineimpliziteKonvertierungzwischen"System.Collections.Generic.List"und"System.Collections.Generic.LinkedList"erfolgt。翻译过来大概是:UnabletodeterminethetypeoftheconditionaloperatorbecauseisnoimplicitconversionbetweenListandLinkedList.我明白为什么编译器会抱怨,但是嘿,来吧。它试图装傻。我可以看到这两个表达式不是同一类型,但有一个共同的祖先,作为奖励,左边的类型也是一个共同的祖先。我相信编译器也能看到它。如果将左侧声明为var,我可以理解错误。我在这里错过了什么?编辑:我接受JamesGunter的解释。也许只是为了说清楚。我可以很好地阅读编译器规范。我想明白为什么。为什么会有人决定以这种方式编写规范。这种设计背后一定有原因。按照詹姆斯的说法,设计原则是“没有惊喜”。此外,CodeInChaos解释了如果编译器尝试从共同祖先推断类型,您可能会遇到的意外情况。表达式(a?b:c)必须解析为一个类型。type将是b或c的类型。如果它们不同(并且没有从一个到另一个的隐式转换),编译器在编译时不知道这是哪种类型。你可能会争辩说它应该推断出有一个共同的根类型,但总是有一个共同的根类型(比如Object)。通常,C#编译器不会尝试猜测您的意思。如果您想要一个公共根类型,请将b和c强制转换为该类型。这个逻辑贯穿于C#的设计之中,偶尔会有点烦人,但更多时候它可以防止你犯错误。由于接口,它们可以有多个不同的共同祖先。可以添加一个要求,即只有在祖先明确的情况下它才会自动转换。但是随后添加该类实现的额外接口突然变成了一个破坏性的变化。这可能是不可取的。例如,假设您使这些类型实现ISerializeable。这不应该改变您的代码的行为,但如果您支持这种到通用接口的转换,它就会。编辑:稍微考虑了一下,注意到这个函数已经有完全相同的问题:TMyFunc(Tleft,Tright)并且这段代码无法编译:ICollectionr=MyFunc(newList(),newLinkedList());因为它不能决定使用哪种类型作为类型参数T所以?:运算符的行为符合重载决议。在确定右侧的类型时,根本不考虑左侧。只有当编译器独立确定右侧的类型时,它才会检查与左侧的赋值兼容性。至于您声称这两种类型“共享一个共同的祖先”:是ICollection、IEnumerable、ICollection、IEnumerable还是Object?编译器应该使用哪种启发式方法来明确确定您想要的类型?编译器只是要求您指定,而不是试图猜测您的意图。只是?:的定义需要相同的类型。你当然可以使用?(ICollection)newList():(ICollection)newLinkedList();或者只使用if/else。根据C#参考,§14.13,[给定]形式b?x:y条件表达式b?x:yb?x:y在您的情况下,X和Y都转换为Z,但这无济于事。在语言中,一般原则是编译器在应用规则时甚至不查看目标变量。简单例子:doublea=7/2;//a变成3.0doublea=7/2;//a变为3.0因此,在阅读本文后,只需将其中一个结果转换为ICollection。我还没有测试过。以上就是C#学习教程:无法确定条件表达式的类型?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
