空条件运算符"无效"数组元素的存在

Mic*_*ens 19 c# arrays null c#-6.0 null-propagation-operator

新的C#6.0空条件运算符是一种方便的工具,用于编写更简洁,更简单的代码.假设有一个客户数组,那么如果customers使用此方法为空,则可以获取null而不是长度(来自MSDN的示例):

int? length = customers?.Length;
Run Code Online (Sandbox Code Playgroud)

同样地,您可以使用以下方法获取null而不是客户:

Customer first = customers?[0];
Run Code Online (Sandbox Code Playgroud)

对于更精细的表达式,如果customers为null,则第一个客户为null,或者第一个客户的Orders对象为null,则返回null:

int? count = customers?[0]?.Orders?.Count();
Run Code Online (Sandbox Code Playgroud)

但是,有一个有趣的情况是不存在的客户,零条件运算符似乎没有解决.我们在上面看到覆盖了一个客户,即customers数组中的条目是否为空.但这与不存在的客户截然不同,例如5在3元素阵列中查找客户或n在0元素列表中查找客户.(请注意,同样的讨论也适用于字典查找.)

在我看来,零条件运算符专注于否定NullReferenceException的影响; IndexOutOfRangeException或KeyNotFoundException独自暴露,在角落里畏缩,需要自生自灭!我提出,在零条件运算符的精神下,它应该能够处理这些情况......这导致了我的问题.

我错过了吗?null条件是否提供了真正涵盖此表达式的任何优雅方式......

customers?[0]?.Orders?.Count();
Run Code Online (Sandbox Code Playgroud)

......没有第0个元素的时候?

Ste*_*eve 27

不,因为它是一个null -conditional运算符,而不是indexoutofrange -conditional运算符,并且仅仅是语法糖,如下所示:

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

if (customers != null && customers[0] != null && customers[0].Orders != null)
{
    int count = customers[0].Orders.Count();
}
Run Code Online (Sandbox Code Playgroud)

您可以看到,如果没有第0个客户,您将获得常规IndexOutOfRangeException.

解决它的一种方法是使用一个检查索引的扩展方法,如果它不存在则返回null:

public static Customer? GetCustomer(this List<Customer> customers, int index)
{
    return customers.ElementAtOrDefault(index); // using System.Linq
}
Run Code Online (Sandbox Code Playgroud)

然后你的检查可能是:

int? count = customers?.GetCustomer(0)?.Orders?.Count();
Run Code Online (Sandbox Code Playgroud)

  • 将 ElementAtOrDefault 信息移近答案的顶部可能会很好。看起来它是一个标准功能,并且完全符合用户的要求。 (2认同)

Sco*_*nen 9

customers?.FirstOrDefault()?.Orders?.Count();
Run Code Online (Sandbox Code Playgroud)

没有零,没有问题.

  • 不要害怕零点。 (2认同)

小智 8

如果您想在没有 NullReference 或 IndexOutOfRange 异常的情况下获取第 n 个元素,可以使用:

customers?.Skip(n)?.FirstOrDefault()
Run Code Online (Sandbox Code Playgroud)