返回 IEnumerable 并调用 ToArray 时的 LINQ 意外行为
本文关键字:LINQ 意外 时的 ToArray IEnumerable 调用 返回 | 更新日期: 2023-09-27 18:35:20
我注意到 LINQ 代码中存在一些奇怪的行为,并使用两种方法将问题简化为以下最小示例:
IA Find(string n)
{
IA result;
if (!_dictionary.TryGetValue(n, out result))
{
throw Exception();
}
return result;
}
IEnumerable<IA> Find(IEnumerable<string> names)
{
return names.Select(Find).ToArray();
}
这按预期工作。
现在,我删除了 .ToArray() 所以该方法如下所示:
IEnumerable<IA> Find(IEnumerable<string> names)
{
return names.Select(Find);
}
此更改将导致不会引发异常,即使某些名称未在 _dictionary 中找到,但存在于 names 参数中也是如此。
是什么导致了 LINQ 的这种(对我来说)意外行为?
这是因为延迟执行。在执行 Linq 之前,不会对其进行计算。
对ToArray()
的调用会导致IEnumerable
的完整枚举,从而发生异常。
第二种方法不枚举IEnumerable
,并且执行将延迟到调用方需要它。
如果您要枚举Find
的结果,例如
var result = Find(new[] { "name" }).ToList();
或
foreach (var found in Find(new[] { "name" }))
{
...
}
然后会发生异常。