空合并运算符的工作原理

本文关键字:工作 合并 运算符 | 更新日期: 2023-09-27 18:01:19

我得到了三个从接口"IFoo"继承的类(classA、classB和classC(;如果使用这个

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接口,但在其他一些情况下则不会。你们觉得怎么样?

空合并运算符的工作原理

在这两个不起作用的例子中,因为??是正确关联的,我们首先尝试确定这个表达式的数据类型:

request.classBitem ?? request.classCitem

如果数据类型不同,则数据类型只能是其中一个输入的数据类型。这里显然没有任何一个方向的转换,因此会出现编译器错误。请注意,编译器将而不是决定这里的数据类型是IFoo,只是因为两个类都碰巧实现了它(如果实现了,如果它们都实现了多个公共接口,会发生什么?(

将此与前两个示例进行比较。在第一个例子中,我们首先考虑这个表达式:

request.classBitem  as IFoo ?? request.classCitem

这个表达式的类型是IFoo,或者是request.classCitem的数据类型。从request.classCitemIFoo的类型有一个转换,所以这显然是被选择的,所以整个表达式的数据类型都是IFoo。然后将其用于确定整个表达式的类型(再次为IFoo(。

第二种情况非常相似,因为??是右联想1,我们首先必须确定的类型

request.classBitem ?? request.classCitem as IFoo

同样,我们可以在IFoorequest.classBitem的数据类型之间进行选择。有一个到IFoo的转换,所以选择了它。

1同时注意,这意味着第一个例子中的括号是多余的。