安全使用 .FirstorDefault()

本文关键字:FirstorDefault 安全 | 更新日期: 2023-09-27 17:56:10

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

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

WorkflowColorItemType associatedColor = ColorItems
    .Where(ci => ci.AssociatedState == WorkflowStateStatus.NotStarted)
    .FirstOrDefault();
if (associatedColor != null)
{
    this.ColorItems.CurrentColor = associatedColor;
}

在此代码片段的上下文中,我永远不会期望 ColorItems 为空,但是将此类片段的每个实例都包含在 try catch 块中,以便我可以处理 ColorItems 集合可能为空的可能性,这是否是一种好的做法?

安全使用 .FirstorDefault()

如果您不希望集合永远为空,并且它为空会在程序中出错,那么首先不要使用 FirstOrDefault,请使用 First 。 由于这不是您遇到预期的情况,因此您需要引起对问题的注意,因为这是出现问题的迹象。

如果集合为空是完全有效的,并且您希望仅在至少有一个项目时才使用第一项,则使用 FirstOrDefault 并提供 null 检查就可以了。

将相同的逻辑应用于为 null 且不为空的集合。 如果预期允许集合为 null,则使用 if 进行检查。 如果不希望允许null集合(对于集合的大多数使用通常都是这种情况),则不应检查,并且希望引发异常,因为它会引起对应该填充该集合的代码中的错误的关注。 尝试捕获异常并继续前进是试图掩盖阻止您查找和修复它的错误。

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

事实上,如果associatedColor为空,则意味着有问题,因此您需要处理它。

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

无论如何,我几乎总是使用FirstOrDefault或类似的东西,比如SingleOrDefault然后我会做空检查。

如果没有结果,则内置的 LINQ 函数(如此处.Where())始终返回一个空枚举,而不是 null。因此,执行.Where()后无需检查null

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

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

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