首页 > 解决方案 > 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() ?? falseemptyCollection?.Any() ?? false同时评估 yield False,这将是预期的行为,但将条件与||运算符结合起来似乎会导致不评估第二个条件,但仅在集合为空的情况下。

在空合并条件中添加一些额外的括号似乎可以解决问题:

Console.WriteLine((nullCollection?.Any() ?? false) || true);
Console.WriteLine((emptyCollection?.Any() ?? false) || true);

产量:

True
True

为什么是这样?这里发生了什么?我错过了什么?

标签: c#

解决方案


根据运算符优先级,条件 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,您将看到所需的行为


推荐阅读