安全使用.FirstorDefault()?

时间:2014-04-02 19:41:33

标签: c# .net

使用Enumerable.FirstorDefault()时,是否需要始终捕获 ArumentNullException ,当操作集合 null 时可以抛出

过去我总是做过这样的事情:

WorkflowColorItemType associatedColor = ColorItems
    .Where(ci => ci.AssociatedState == WorkflowStateStatus.NotStarted)
    .FirstOrDefault();

if (associatedColor != null)
{
    this.ColorItems.CurrentColor = associatedColor;
}

在这段代码的上下文中,我绝对不会期望ColorItems为null,但是在try catch块中封装像这样的片段的每个实例是一个好习惯,这样我就可以处理ColorItems集合可能出现的机会。空?

3 个答案:

答案 0 :(得分:2)

如果你不希望这个收藏品是空的,并且你的程序中的错误是空的,那么就不要使用{{1首先,使用FirstOrDefault。因为你不想进入,所以你想引起对问题的关注,因为这表明出现了问题。

如果它对于集合是完全有效的,并且您只想在至少有一个项目的情况下使用第一个项目,那么使用First并提供空检查就可以了。

将相同的逻辑应用于集合为空,而不是空。如果期望允许集合为null,则使用FirstOrDefault检查它。如果它期望该集合被允许为if(通常情况下大多数情况下都使用集合)那么你就不应该检查,而你想要抛出异常,因为它会引起对应该填充该集合的代码中的错误的注意。试图捕捉异常并继续前进是试图掩盖错误,这会阻止您找到并修复它

答案 1 :(得分:1)

是的,当然。你需要一直保持防守。

实际上,如果associatedColor为null,则表示存在错误,因此您需要处理它。

事实上,您的代码曾经被包装在try / catch块中以处理异常,因为异常是“昂贵的”,这是处理特殊情况的更便宜和更好的方式。

在任何情况下,我几乎总是使用FirstOrDefault或类似的东西,如SingleOrDefault然后我会进行空检查。

答案 2 :(得分:0)

内置的LINQ函数(如此处的.Where())如果没有结果,则返回空的枚举,而不是null。因此,在执行.Where()

后无需检查空值

根据ColorItems的来源,您应该在对象上检查null:

if (ColorItems != null) 
{
}
else
{
}

没有必要在代码周围放置try / catch块,但是为了安全起见,你应该检查null。事实上,在像这样的场景中使用try / catch,你可以检查一个空对象,这是一个糟糕的编程习惯。