使用 ??(空值合并运算符)时的奇怪操作符优先级

23

最近我遇到了一个奇怪的错误,我的代码中我将一个int?与一个字符串连接起来,然后又在此之后添加了另一个字符串。

我的代码基本上等同于这个:

int? x=10;
string s = "foo" + x ?? 0 + "bar";

惊人的是,这段代码将会运行和编译,而不会出现警告或不兼容类型错误。以下代码同样如此:

int? x=10;
string s = "foo" + x ?? "0" + "bar";

然后这会导致一个意外的类型不兼容错误:

int? x=10;
string s = "foo" + x ?? 0 + 12;

这个更简单的例子也会:

int? x=10;
string s = "foo" + x ?? 0;

有人能向我解释一下这是如何工作的吗?


1
一个相关的问题:https://dev59.com/GnA75IYBdhLWcg3wlqET#3218268 - Eric Lippert
1
这里是一个链接,不会让我的答案发光... https://dev59.com/GnA75IYBdhLWcg3wlqET - ChaosPandion
2个回答

27

空值合并运算符的 优先级 很低,所以你的代码被解释为:

int? x = 10;
string s = ("foo" + x) ?? (0 + "bar");
在这个例子中,两个表达式都是字符串,所以它可以编译,但不会产生你想要的结果。在你下一个例子中,??操作符的左侧是一个字符串,但右侧是一个整数,因此它不能编译:
int? x = 10;
string s = ("foo" + x) ?? (0 + 12);
// Error: Operator '??' cannot be applied to operands of type 'string' and 'int'

当然的解决方案是添加括号:

int? x = 10;
string s = "foo" + (x ?? 0) + "bar";

啊,因为优先级低,所以两边几乎形成了两个独立的表达式。 - Earlz
这就是为什么 int x = 10; string s = "foo" + x ?? "0"; 能够工作的原因。 - Earlz

11

??运算符的优先级低于+运算符,因此您的表达式实际上是这样工作的:

string s = ("foo" + x) ?? (0 + "bar");

首先将字符串"foo"和变量x的字符串值连接起来,如果结果为null(这是不可能的),则连接字符串"bar"和数字0的字符串值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接