0 或多个项目的 LINQ Single() 异常

Posted

技术标签:

【中文标题】0 或多个项目的 LINQ Single() 异常【英文标题】:LINQ Single() Exception for 0 or multiple items 【发布时间】:2012-11-21 17:08:30 【问题描述】:

我有一些IEnumberable 的项目集合。我使用.Single() 在集合中查找特定对象。

我选择使用Single(),因为应该只有一个特定的项目。但是,如果一个不存在,那么我需要创建它并将其添加到集合中。

我的问题是Single() 如果没有与谓词匹配的项目或有多个项目,则会引发相同的错误。我的想法是将Single() 调用放在try 中并捕获异常,添加项目,然后继续。但是,由于这两种情况都会抛出InvalidOperationException,我如何判断它是由于没有物品还是由于多个物品?

我知道我可以使用First(),但这并不能强制执行应该只有一个的想法(无需做额外的工作)。

我也可以在Single() 调用之前使用Count(),但这似乎破坏了Single() 的意义

【问题讨论】:

【参考方案1】:

你想要的是SingleOrDefault()

“或默认值”实际上意味着它返回 null(对于引用类型)或任何非引用类型的默认值。您需要新建一个对象来代替它。

【讨论】:

...如果你想链接空检查,可以使用类似napoleonss.wordpress.com/2011/12/20/my-check-null的东西。适用于类型的默认值 嗯,它返回元素类型的默认值。这对于引用类型是 null,但对于不可为空的值类型显然不是... @JonSkeet 你是对的。我以为他说的是引用类型。 @DigitalD:是的,可能在这种情况下。只是您的第二句话听起来像是您将方法命名为SingleOrNull,这是不合理的。【参考方案2】:

我不建议在这种情况下使用 try/catch,因为使用异常来做出逻辑决策会耗费资源。

我建议使用SingleOrDefault(),并检查结果是否为空。如果是。做你的创作。

【讨论】:

“资源昂贵” - 有点过时/不正确的观点。请参阅此处提供的 Rico Mariani 链接。 ***.com/q/891217/16391。我同意使用异常来做出合乎逻辑的决策是一个糟糕的设计选择。【参考方案3】:

当集合中有多个项目时,SingleOrDefault 将引发异常。您必须事先手动检查尺寸。

var singleItem = list.Count() == 1 ? list.Single() : null;

也许最好只做你自己的扩展函数。

【讨论】:

以上是关于0 或多个项目的 LINQ Single() 异常的主要内容,如果未能解决你的问题,请参考以下文章

Java 8 流中的 LINQ Enumerable.Single() [重复]

Linq特取操作之ElementAt,Single,Last,First源码分析

LINQ On DbContext.Set()

linq 学习笔记

EF LINQ 包括多个和嵌套的实体

一个上下文引用 LINQ 查询引发多个引用异常 - BUG?