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

Wil*_*ert 2 .net c# linq arrays

我注意到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();
}
Run Code Online (Sandbox Code Playgroud)

这按预期工作.

现在,我删除了.ToArray(),因此该方法如下所示:

IEnumerable<IA> Find(IEnumerable<string> names)
{
    return names.Select(Find);
}
Run Code Online (Sandbox Code Playgroud)

此更改将导致不抛出异常,即使在_dictionary中找不到某些名称,但在names参数中也存在这些名称.

是什么原因导致LINQ的意外行为(对我而言)?

Jod*_*ell 14

这是因为延期执行.在执行之前,不会评估Linq.

调用ToArray()导致完整的枚举,IEnumerable从而发生异常.

第二种方法没有枚举,IEnumerable并且执行被推迟到调用者需要它.


如果你要枚举Find例如的结果

var result = Find(new[] { "name" }).ToList();
Run Code Online (Sandbox Code Playgroud)

要么

foreach (var found in Find(new[] { "name" }))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后会发生异常.