我观察到空合并运算符和 OR 运算符的一些奇怪行为,想知道是否有人可以阐明这一点。
var nullCollection = null as IEnumerable<string>;
var emptyCollection = Enumerable.Empty<string>();
Console.WriteLine(nullCollection?.Any() ?? false || true);
Console.WriteLine(emptyCollection?.Any() ?? false || true);
产生以下输出:
True
False
简单评测
nullCollection?.Any() ?? false
或 emptyCollection?.Any() ?? false
两者产量False
,这将是预期的行为,但将条件与 ||
结合使用运算符似乎导致不评估第二个条件,但仅在集合为空的情况下。向空合并条件添加一些额外的括号似乎可以解决问题:
Console.WriteLine((nullCollection?.Any() ?? false) || true);
Console.WriteLine((emptyCollection?.Any() ?? false) || true);
产量:
True
True
为什么是这样?这里发生了什么?我错过了什么?
最佳答案
根据operators precedence , 条件 OR 运算符 ||
具有比空合并运算符更高的优先级 ??
.
根据null-coalescing operator眼镜:
The
??
operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.
因此,在您的代码中需要添加一个括号来确定正确的执行顺序和
??
运算符(operator)评价。没有括号的这个
nullCollection?.Any()
返回 null
,因此 ??
运算符返回 false || true
的结果(由于优先级,如上所述),始终是 true
.emptyCollection?.Any()
结果不是null
并返回 false
,因此右侧 false || true
没有被评估,编译器足够聪明来理解它。添加括号强制编译器执行运算符的预期执行:
(nullCollection?.Any() ?? false)
返回 false
因为左边操作数是
null
并执行右侧操作数。 (emptyCollection?.Any() ?? false)
也返回 false
, 左边操作数不是
null
右侧没有执行。 false || true
的逻辑 OR返回 true
在这两种情况下,您都会看到所需的行为
关于C# 空合并运算符与空集合和空集合之间的 OR 运算符结合时的行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60186805/