应用程序意外崩溃,堆栈溢出错误。经过研究,我发现崩溃的原因是遵循以下代码:
foreach (var item in items)
{
result = result.Concat(item.Data);
}
这是多个IEnumerable
的串联。当items
包含10,000个元素时,应用程序崩溃。
SelectMany
解决了这个问题。但还是......
为什么Concat
扩展导致堆栈溢出?
答案 0 :(得分:8)
请注意,Concat
的结果不是集合 - 它是查询。
所以你的结果"实际上是
Enumerable.Concat(item10000.Data,
Enumerable.Concat(item9999.Data,
....
Enumerable.Concat(item2.Data,
item1.Data))));
生成嵌套查询时会导致堆栈溢出。
另一个选择是创建一个列表并每次添加它:
var list = new List<something>();
foreach (var item in items)
{
list.AddRange(item.Data);
}
这基本上是SelectMany
的作用(但是使用延迟的枚举器,而不是List
):
result = items.SelectMany(item => item.Data);
答案 1 :(得分:1)
当你要求第10,000个concat得到它的结果时,它会询问第9,999次连续操作它的结果,意图在它之后产生更多的值。&#39;完成后,然后第9,999次concat操作将询问9,998th concat的结果,它会询问9,997th concat的结果,最后你要么得到第1次concat,要么你的堆栈空间不足。
正如您在问题中所提到的那样,SelectMany
是压缩序列序列的正确操作。