C# 空合并运算符和带as的转换

C# 空合并运算符和带as的转换,c#,C#,为什么我不能将空合并操作符(??)与使用as的转换一起使用? 根据我的理解,如果类型不是实例的类型,则使用as进行强制转换将产生null,因此我认为它将尝试表达式的正确部分 以下是我的意思的一个例子: void Main() { a instance = new c(); var test = (instance as d) ?? (instance as c) ?? (instance as b); } public class a {} public class b :

为什么我不能将空合并操作符(
??
)与使用
as
的转换一起使用? 根据我的理解,如果类型不是实例的类型,则使用
as
进行强制转换将产生
null
,因此我认为它将尝试表达式的正确部分

以下是我的意思的一个例子:

void Main()
{
    a instance = new c();

    var test = (instance as d) ?? (instance as c) ?? (instance as b);
}

public class a {}
public class b : a {}
public class c : a {}
public class d : a {}
我得到的错误是:

Operator '??' cannot be applied to operands of type 'UserQuery.d' and 'UserQuery.c'

我理解在这种情况下使用var是不合适的,但即使使用
dynamic
a
(基本类型),我也会收到相同的错误消息。问题似乎与
运算符有关。

这与此无关,只是因为编译器无法确定(d??c)的返回类型。 您可以通过将至少一个操作数强制转换为
a

var test = (instance as d) ?? (a) (instance as c) ?? (instance as b);
这是观察这种行为的较短样本

c instancec = new c();
d instanced = new d();

a foo = instancec ?? instanced; // Compile error even if we declare foo as a

您需要能够在编译时定义
test
变量的类型。您试图合并的3个表达式都是不同类型的(
d
c
b

更具体地说,coalesce操作符需要两个表达式本质上是相同的类型。每个合并操作都是在操作符的每一侧使用不同的类型执行的。要阅读有关此要求的完整详细信息,请检查以下答案:


您可以将每个表达式强制转换为
a
,然后就可以进行编译,因为
test
的类型可以确定为
a
。但是那会破坏你练习的目的,不是吗?

var
是一个编译时构造。它不支持动态类型

因此,你试图做的是毫无意义的。
test
的唯一可能类型是
a
——您已经有了它

有意义的(合法的)是这样的:

var someValue = (obj as d)?.someProperty ?? (obj as c)?.someOtherProperty;

在本例中,没有动态类型-我们只是有一种不同的方法从两种不同的类型中获取等效值。然而,与使用适当的多态性或至少使用
dynamic

将代码简化为以下内容相比,这听起来也是个坏主意:

var test = (instance as d) ?? (instance as c);

您希望
测试的类型是什么?是
d
还是
c
?类型只能在编译时确定。编译器不会为您隐式地将其转换为相应的基类型。因此,您需要按照@Ksv3n的建议手动执行此操作。

“为什么我不能使用”-这意味着一个错误,您可以将其添加到问题中以帮助搜索等吗?因为
d
不能是
c
c
不能是
b
。您没有在此处指定确切的错误消息。看起来这可能与以下事实有关:对于
var test=…
,编译器必须能够确定确切的类型,但您正在尝试将其设置为三种不同类型之一。
为什么我不能将空合并运算符(?)与使用as的转换一起使用?
您可以。您看到的问题与该问题完全无关。
var test=(a)(实例为d)??(a) (例如c)??(a) (例如b)
将编译,但我不确定它是否非常有用。@Ksv3n当然,为什么要这样做<代码>d
不是从
c
派生的。问题仍然是一样的-类型不匹配。我更新了我的问题。事实上,
var
是一个错误的选择,但是即使使用
dynamic
我也有同样的行为。@Shimrod使用
dynamic
,首先使用
作为
也没有意义。你对你在这里的小实验到底有什么期望?我知道,这只是为了理解为什么
操作符在这里不起作用,因为当类型不正确时,操作数会产生
null
。事实上,这会破坏目的。我用
dynamic
更新了这个问题,应该已经解决了返回类型的问题,但是错误消息(我之前添加的)显示问题出在
??
操作符中。好的,第一次读取时没有得到它。你是从哪里得到这些信息的?你可以在这个答案中读到关于这个操作符如何处理类型的更多细节:我想在我的例子中,我落在了最后一点。谢谢你提供的信息,我会将你的答案标记为已接受!(也许您可以更新您的答案以添加此信息?)