空合并运算符的工作原理
本文关键字:工作 合并 运算符 | 更新日期: 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.classCitem
到IFoo
的类型有一个转换,所以这显然是被选择的,所以整个表达式的数据类型都是IFoo
。然后将其用于确定整个表达式的类型(再次为IFoo
(。
第二种情况非常相似,因为??
是右联想1,我们首先必须确定的类型
request.classBitem ?? request.classCitem as IFoo
同样,我们可以在IFoo
和request.classBitem
的数据类型之间进行选择。有一个到IFoo
的转换,所以选择了它。
1同时注意,这意味着第一个例子中的括号是多余的。