【问题标题】:C# 6.0 null-conditional operator in if statementsif 语句中的 C# 6.0 空条件运算符
【发布时间】:2021-05-06 10:15:53
【问题描述】:

谁能解释一下 if 语句中空条件运算符的逻辑?

想象一下下面的代码

List<string> items = null;
if (items?.Count == 0)
{
    Console.WriteLine("error");
}
else
{
    Console.WriteLine("OK");
}

上面将打印OK。为什么下一个块不编译时它编译?

if (items?.Any())    // won't compile but if (items?.Count() == 0) would
{
    ...
}

我猜是?当检测到 null 并跳过整个 if 时将停止执行,但为什么“?.Any()”不是这种情况?仅仅因为它是一个方法,而“count”是一个属性?

为什么 Linq 扩展方法 Any() 需要从 Nullable 到 bool 的显式转换,而 Count() == 0 编译时不需要 Nullable 到 int 的转换?

【问题讨论】:

  • == 上有一个重载来解除比较并且仍然返回真/假,所以魔术就在Nullable&lt;T&gt; 上的== 运算符中。如果您尝试if (items?.Any() == true),它将编译。
  • 请注意,在 C# 9 中,您可以将其写为 if (items is { Count: &gt; 0 })。你可能会也可能不会觉得更清楚。

标签: c# linq null-conditional-operator


【解决方案1】:

如果items 为空,那么items?.Count 也为空。
null == 0 是一个导致错误的比较。所以if 很高兴。

items?.Any() 也将为 null - 而if(null) 无效,因为 null 不是布尔值,不能转换为布尔值。

因此您只需提供一个备用布尔值:

if (items?.Any() ?? false) {

}

会成功的

【讨论】:

  • if (items?.Any() == true) 我认为更具可读性
  • @HansKilian 这是一个偏好问题,我(显然)是空合并运算符的根。但看看性能是否存在差异会很有趣。
  • 我认为可读性通常比性能更重要。至少在我工作的系统上。我将性能留给编译器 :) 但是你说得对,当然,更具可读性是一个偏好问题。
  • @David 这是因为0null 都可以转换为int?(可以为空的int)。
【解决方案2】:

考虑null 案例。

if (items?.Count == 0) 中变成if (null == 0) 并给出错误。

但在if (items?.Any()) 中,它变成了if (null),这是无效的。

您可以使用if (items?.Any() == true)if (items?.Any() ?? false) 或类似名称。

我注意到 items.Count == 0 是一个错误,但 items == null 在您的第一个示例中返回 Ok。
这很奇怪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-18
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 2022-11-13
    • 2020-12-05
    相关资源
    最近更新 更多