使用LINQ时出现“Sequence contains no elements”异常,即使没有使用Single方法。

49

在下面的 LINQ 中,我没有使用 Single,但仍然会收到“序列中不包含元素”的异常:

allNames = StockCollection.Where((s) => s.Name.IndexOf("A") == 0)
                          .Select((s) => s.Name)
                          .Aggregate((namesInfo, name) => namesInfo += ", " + name);

当没有以名称'A'开头的库存时,将出现此异常。

似乎有一个扩展方法期望至少存在一个满足条件的元素,但这并不是预期的。

请您提供最佳解决方案来解决此问题好吗?

先行致谢。

3个回答

84
正如Dennis Traub指出的那样,当源序列为空时,您正在使用的Aggregate过载会抛出异常。
显而易见的解决方法是使用接受初始种子的Aggregate的其他过载(您需要string.Empty),但这将导致结果中出现一个前导逗号,您必须摆脱它。
编辑:您可以通过.DefaultIfEmpty(string.Empty)跳过此步骤,然后使用现有的Aggregate过载。这不会产生前导逗号。)
无论如何,像这样使用Aggregate来连接字符串并不是一个好主意(会产生Schlemiel the Painter's algorithm)。这是我编写查询的方式:
allNames = string.Join(",", StockCollection.Select(s => s.Name)
                                           .Where(name => name.StartsWith("A"));

在 .NET 3.5 中,您需要使用 ToArray()Where 的结果转换为数组。

非常感谢您的回复,我现在要尝试一下这个方法。但是我仍然想知道为什么聚合会抛出异常。 - D J
@D J:为什么?它能返回什么有意义的值?也许是返回类型的默认值(在这种情况下是null),但我不想要那个。 - Ani
1
问题就像是我们在运行时不知道我们的集合是否有任何对象?因此它不应该抛出异常,或者可以返回默认值。 - D J
7
+1 for DefaultIfEmpty,这个方法在处理比字符串更复杂的示例时效果很好。 - Myster
1
如果可以的话,我会给你第二个点赞,感谢“在.NET 3.5中”的提示! - Neil Vass

23

使用空种子。

new string[]{}.Aggregate("", (a,b)=> a+b )

3
我认为,应该使用string.Empty而不是""。 - Nikita

6

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接