【问题标题】:C# 6 null conditional operator check for .Any()?C# 6 空条件运算符检查 .Any()?
【发布时间】:2015-10-26 09:09:32
【问题描述】:

在此处显示的示例 (and on numerous other websites) 中,关于空条件运算符,它声明

int? first = customers?[0].Orders.Count(); 

可用于获取第一位客户的计数。但是此语句不检查集合中是否存在客户,并且可能会引发索引超出范围异常。负责检查元素是否存在的正确(最好是单行)语句应该是什么?

【问题讨论】:

  • 猜猜,客户?检查 icustomers 数组是否为空,在您的情况下它不是,但客户数组为空。所以你在索引 0 处没有任何元素
  • 还有订单?如果 Orders 为 NULL,则会出错。你必须使用:int?第一个 = 客户?[0].Orders?.Count();

标签: c# c#-6.0


【解决方案1】:

null 条件运算符用于有条件地访问null,但这不是您遇到的问题。

您正试图访问一个空数组。您可以将其转换为使用 FirstOrDefault 访问 null 的情况,并在其上使用运算符:

int? first = customers.FirstOrDefault()?.Orders.Count(); 

如果数组不为空,它将对第一项进行操作,如果为空,FirstOrDefault 将返回 null,这将由 null 条件运算符处理。

编辑:正如 cmets 中提到的 w.b,如果您正在寻找第一个以外的其他项目,您可以使用 ElementAtOrDefault 而不是 FirstOrDefault

【讨论】:

  • Orders 为空怎么办?
  • @Meehow 这不是 OP 所要求的。但如果是这样.. 只需在此处使用条件访问运算符。
  • 此 Microsoft 文档是否有错误或不完整。? msdn.microsoft.com/en-us/library/dn986595.aspx?.
  • 如果我实例化“var customers = new List()”(我认为是正常的方式),那么示例“客户第一 = 客户?[0];”引发“索引超出范围”异常。为了使该示例正常工作,您必须使用人为的“List tokens = null”进行实例化。这些示例似乎表明将处理任何“超出范围”的异常。
  • @WillC 不应处理“超出范围”异常。只有空引用异常。我在该文档中没有看到任何其他建议。
【解决方案2】:

您可以使用 LINQ 的 DefaultIfEmpty,如果查询的集合为空,它将产生一个单例 IEnumerable

int? first = customers?.DefaultIfEmpty().First().Orders.Count();

或者如果你想使用索引:

int? first = customers?.DefaultIfEmpty().ToArray()[0].Orders.Count();

【讨论】:

    【解决方案3】:

    如果我正确理解了这个问题,您是在问是否有内置(或简洁)的方法来防止IndexOutOfRangeExceptions。您最接近它的方式是:

    myArray?.Length > 42 ? myArray[42] : null
    

    或@w.b。提到,利用 ElementAtOrDefault:

    myArray?.ElementAtOrDefault(42) 
    

    这两者都可以防止NullReferenceExceptionIndexOutOfRangeException

    【讨论】:

    • 我会说FirstOrDefault 是内置且简洁的。
    • @l3arnon 仅当您追求的索引为 0 时。如果它是 42 怎么办?
    • @ErenErsönmez - 有ElementAtOrDefault
    • @w.b 我其实不知道这个扩展存在。
    猜你喜欢
    • 2016-10-25
    • 2016-06-08
    • 1970-01-01
    • 2015-02-14
    • 2017-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多