2

我注意到 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 的意外行为?

4

1 回答 1

14

这是因为延迟执行。在您执行 Linq 之前,它不会被评估。

调用会ToArray()导致完整的枚举,IEnumerable因此会发生异常。

第二种方法不枚举IEnumerable并且执行被推迟到调用者需要它。


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

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

或者

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

那么就会发生异常。

于 2013-10-14T14:32:57.817 回答