返回IEnumerable并调用ToArray时出现LINQ意外行为

时间:2013-10-14 14:30:31

标签: c# .net arrays linq

我注意到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意外行为的原因是什么?

1 个答案:

答案 0 :(得分:14)

因为延期执行。在执行Linq之前,不会对其进行评估。

ToArray()的调用会导致IEnumerable的完全枚举,从而发生异常。

第二种方法不会枚举IEnumerable,并且会延迟执行,直到调用者需要它为止。


如果您要枚举Find例如

的结果
var result = Find(new[] { "name" }).ToList();

foreach (var found in Find(new[] { "name" }))
{
    ...
}

然后会发生异常。