null-coalsescing运算符如何工作

时间:2016-08-08 08:32:20

标签: c# .net null-coalescing-operator

我有三个类(classA,classB和classC)继承自接口'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接口,但在其他情况下则不会。你们觉得怎么样?

1 个答案:

答案 0 :(得分:5)

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

request.classBitem ?? request.classCitem

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

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

request.classBitem  as IFoo ?? request.classCitem

此表达式的类型为IFoorequest.classCitem的数据类型。从request.classCitemIFoo的类型转换,因此显然已选中,因此整个表达式的数据类型为IFoo。然后用它来确定整个表达式的类型(同样,IFoo)。

第二种情况非常相似,因为??是右关联 1 ,我们首先要确定类型:

request.classBitem ?? request.classCitem as IFoo

同样,我们可以在IFoorequest.classBitem的任何数据类型之间进行选择。已经转换为IFoo,因此可以选择。

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