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
更新了这个问题,应该已经解决了返回类型的问题,但是错误消息(我之前添加的)显示问题出在??操作符中。好的,第一次读取时没有得到它。你是从哪里得到这些信息的?你可以在这个答案中读到关于这个操作符如何处理类型的更多细节:我想在我的例子中,我落在了最后一点。谢谢你提供的信息,我会将你的答案标记为已接受!(也许您可以更新您的答案以添加此信息?)