C# 空合并运算符与空集合和空集合之间的 OR 运算符结合时的行为不同

标签 c#

我观察到空合并运算符和 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两者产量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/

    相关文章:

    c# - C#中的简单几何形状识别

    c# - 插入存储在数据库中的字符串

    c# - vtables是如何在c++和c#中实现的?

    c# - 如何在运行时动态地将值传递给 ObjectDataProvider.MethodParameters

    c# - 如何知道 IEnumerable<ValueType> 是否为空,而不计算全部?

    C#。引用扩展方法的引用返回委托(delegate)

    c# - 顶级任务导致错误 "The current SynchronizationContext may not be used as a TaskScheduler."

    c# - 将数据绑定(bind)到嵌套的 ListView

    c# - 在 EF 4 中,您更喜欢 ObjectSet 还是 CreateQuery?

    c# - 缓冲 log4net 调试消息以在错误时显示它们?