我有三个类(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接口,但在其他情况下则不会。你们觉得怎么样?
答案 0 :(得分:5)
在两个不起作用的示例中,由于??
是右关联的,我们首先尝试确定此表达式的数据类型:
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 同时请注意,这意味着第一个例子中的括号是多余的。