c# - C# Null 合并运算符在 Null 和空集合之间与 OR 运算符结合时表现不同
问题描述
我观察到空合并运算符与 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
同时评估 yield False
,这将是预期的行为,但将条件与||
运算符结合起来似乎会导致不评估第二个条件,但仅在集合为空的情况下。
在空合并条件中添加一些额外的括号似乎可以解决问题:
Console.WriteLine((nullCollection?.Any() ?? false) || true);
Console.WriteLine((emptyCollection?.Any() ?? false) || true);
产量:
True
True
为什么是这样?这里发生了什么?我错过了什么?
解决方案
根据运算符优先级,条件 OR 运算符||
的优先级高于空合并运算符??
。
根据空合并运算符规范:
??
如果左侧操作数的计算结果为非空,则运算符不会计算其右侧操作数。
因此,需要在您的代码中添加一个括号来做出正确的执行顺序和??
运算符评估。
没有括号 thisnullCollection?.Any()
返回null
,因此??
运算符返回false || true
(因为优先级,如上所述)的结果,它始终是true
。
emptyCollection?.Any()
result is notnull
并且返回false
,因此不对右侧false || true
进行评估,编译器足够聪明,可以理解它。
添加括号强制编译器执行运算符的预期执行:
(nullCollection?.Any() ?? false)
返回false
,因为左侧操作数是null
并且右侧操作数被执行。(emptyCollection?.Any() ?? false)
也返回false
,左侧操作数null
不执行,右侧不执行。
两种情况下的逻辑或false || true
返回true
,您将看到所需的行为
推荐阅读
- google-cloud-platform - Google Cloud Vision - 如果我只有它的 url,如何从我的存储桶中传递图像?
- r - 如何重新排序以填充堆积条形图中的列
- angular - 解析器未在 Angular 中返回数据
- mongodb - 猫鼬:填充与 findById
- java - 为什么这个条件语句的计算结果为真?
- python - 我的 __dict__ 在哪里?从命名元组继承的类
- c# - 在 C# 中与嵌套表达式树作斗争
- .net - Winform.MonthCalendar.Size 在 .CalendarDimensions 更新后未更新
- python - drf中的UniqueValidator
- java - 在另一个完成后优雅地停止一个无限通量