我观察到null合并运算符与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
为什么是这样?这里发生了什么?我想念什么?
根据运算符的优先级,条件OR运算符的||
优先级高于null-coalescing运算符??
。
根据null推销操作员规范:
??
如果左侧操作数的计算结果为非null ,则运算符不会评估其右侧操作数。
因此,在您的代码中需要添加括号以使执行和??
操作员评估的顺序正确。
如果不带括号,则nullCollection?.Any()
返回null
,因此??
运算符将返回的结果false || true
(由于上述优先级),始终为true
。
emptyCollection?.Any()
结果不是null
并且返回false
,因此右边false || true
没有被评估,编译器足够聪明来理解它。
添加括号会强制编译器执行运算符的预期执行:
(nullCollection?.Any() ?? false)
返回,false
因为左侧操作数为,null
而右侧操作数已执行。(emptyCollection?.Any() ?? false)
还返回false
,左侧操作数null
不执行,右侧不执行。两种情况下的逻辑“或”false || true
返回true
,您将看到期望的行为
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句