2017-03-06 67 views
2

我有以下string列表:如果条件为?操作空对象

List<string> Emails = new List<string>(); 

想看看是否有任何值,或返回一个空字符串:

string Email = Emails[0] ?? ""; 

上面的代码抛出一个异常:

指数超出范围。必须是非负的并且小于 的大小。参数名:索引

但改变??运营商简单if声明,它工作正常:

if (Emails.Count > 0) 
    Email = Emails[0]; 
else 
    Email = ""; 

缺少什么我在这里? 当列表为空时,应该Emails[0]不是null

谢谢。

+4

电子邮件[0]会尝试列表访问的第一个项目 - 这就是为什么它抛出异常 – Fabio

+2

这里的问题是两段代码是不等价的。在第二部分中,在尝试访问数组元素Emails [0]之前,您正确地检查了数组边界“Emails.Count> 0”。在第一部分中,您正在使用空合并运算符正确检查索引零处的元素是否为null,但是您没有正确检查数组边界 - 这是您得到的异常。 –

+1

该列表不为空,因此使用'??'没有意义。第一个项目也不为零 - 没有第一个项目。使用'FirstOrDefault'或者一个明确的检查是可行的。如果你关心第一个项目,是不是更好地切换到更合适的容器,比如'Queue <>'? –

回答

10

我建议将其改为:

string Email = Emails.FirstOrDefault() ?? ""; 

如果列表是空的,Emails[0]不为空,它只是不存在。

编辑:对于字符串和REF类型的作品,如果你有一个值类型,例如整型,你会得到默认(INT)是0作为空集的FirstOrDefault的结果

+0

'EmailO'上不存在'FirstOrDefault' –

+3

@Koby它是''using System.Linq;'namespace中找到的'Enumerable'的扩展方法。 –

+1

@Maksim快速打开答案!如果您想提高答案的质量,请提供有关OP提供的两段代码以及问题出在哪里的说明,然后解释您的解决方案如何帮助他。这将为这个问题的未来读者增加价值。 –

3

Emails[0]将尝试访问列表的第一项 - 这就是为什么它会抛出异常。

您可以使用“可读” DefaultIfEmpty方法宣告“默认”值,如果集合为空

string Email = Emails.DefaultIfEmpty("").First(); 
0
string Email = Emails[0] 

这就是问题所在。 ??只会检查左边的内容是否为null并据此采取行动。

您似乎有一个错误的观念,认为存在索引0的空列表null。这绝对不是这种情况。这两个列表在语义上非常不同:

var emptyList = new List<string>(); 
var someList = new List<string>() { null }; 

在你的代码试图在一个空表的零位访问该项目。这是一个索引超出范围的例外,因为没有这样的项目。在对??运算符进行评估之前抛出异常。

0

使用电子邮件[0]会抛出异常,因为您访问不存在的元素0 Maksim建议Emails.FirstOrDefault()将返回null,如果列表为空,您检查?联合运营商