我得到了三个类(classA,classB和classC),它们从接口(interface)“IFoo”继承;如果使用这个

var fooItem = (request.classAitem ?? (request.classBitem  as IFoo ?? request.classCitem))

或者
var fooItem = (request.classAitem ?? request.classBitem ?? request.classCitem as IFoo)

它工作正常,但其他组合甚至无法编译:
var fooItem = (request.classAitem as IFoo ?? request.classBitem ?? request.classCitem)

或者
var fooItem = (request.classAitem ?? request.classBitem ?? request.classCitem) as IFoo

在我看来,在某些情况下,编译器会隐式地将子类拆箱到其IFoo接口(interface),但在其他情况下则不会。你们有什么感想?

最佳答案

在这两个都不起作用的示例中,由于??是右关联的,因此我们首先尝试确定此表达式的数据类型:

request.classBitem ?? request.classCitem

如果数据类型不同,则数据类型只能是其输入之一的数据类型。显然,在这两个方向上都没有可用的转换,因此您会遇到编译器错误。请注意,编译器不会仅仅因为这两个类都碰巧实现了数据就决定这里的数据类型为IFoo(如果确实做到了,那么,如果它们都实现了多个通用接口(interface)会发生什么呢?)

将此与您的前两个示例进行比较。首先,我们首先考虑以下表达式:
request.classBitem  as IFoo ?? request.classCitem

此表达式的类型为IFoorequest.classCitem的任何数据类型。从request.classCitem的类型转换为IFoo,因此显然已选择,因此整个表达式的数据类型为IFoo。然后将其用于确定整体表达式的类型(再次为IFoo)。

第二种情况非常相似,因为??是正确的associative1,我们首先必须确定以下类型:
request.classBitem ?? request.classCitem as IFoo

同样,我们可以在IFoorequest.classBitem的任何数据类型之间进行选择。有一个到IFoo的转换,因此被选中。

1还要注意,这意味着第一个示例中的括号是多余的。

关于c# - 空推算运算符如何工作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38824545/

10-16 21:10