关于c#:奇怪的运算符优先级与??

Weird operator precedence with ?? (null coalescing operator)

最近我遇到了一个奇怪的bug,我将一个字符串与一个int?连接起来,然后在后面添加另一个字符串。

我的代码基本上等同于:

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

令人惊讶的是,它运行和编译时不会出现警告或不兼容的类型错误,这也会:

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

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

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

这个简单的例子也一样:

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

有人能给我解释一下这是怎么回事吗?


空合并运算符的优先级非常低,因此您的代码被解释为:

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

在本例中,这两个表达式都是字符串,因此它可以编译,但不执行您想要的操作。在下一个示例中,??运算符的左侧是字符串,但右侧是整数,因此它不会编译:

1
2
3
int? x = 10;
string s = ("foo" + x) ?? (0 + 12);
// Error: Operator '??' cannot be applied to operands of type 'string' and 'int'

当然,解决方法是添加括号:

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


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

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

首先,串"foo"和串x的值被连接起来,如果该值为空(不能为空),那么串0和串"bar"的值被连接起来。