You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LINQ中.Where方法底层实现及链式调用枚举次数疑问

关于LINQ链式Where调用的枚举次数解惑

你的理解有误,实际仅会对原始集合执行一次枚举,核心原因在于LINQ的「延迟执行」特性,结合Where方法的迭代器实现来具体解释:

1. 延迟执行的本质

Where是LINQ中的延迟执行操作,它返回的IEnumerable<TSource>并不会立即遍历原始集合。只有当后续调用立即执行操作(比如ToList()、Count())时,才会触发真正的枚举流程。

2. 链式调用的执行流程

以collection.Where(pred1).Where(pred2).ToList()为例,执行过程是流水线式的:

  • 当ToList()开始构建列表时,它会遍历第二个Where返回的序列;
  • 第二个Where遍历第一个Where返回的序列;
  • 第一个Where遍历原始集合。

整个过程是单轮遍历、逐个处理:原始集合的每个元素被取出后,先经过pred1判断,符合条件的再传入pred2判断,最终符合条件的元素才会被添加到List中。不存在“第一个Where先遍历完整个集合生成中间结果,再由第二个Where遍历中间结果”的情况。

3. 结合Where的实现代码理解

你给出的Where实现中使用了yield return,这使得方法成为一个迭代器:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource,bool> predicate)
{
    foreach (TSource element in source)
        if (predicate (element))
            yield return element;
}
  • 调用Where时,方法并不会立即执行foreach循环,只有当这个迭代器被遍历(比如被后续的Where或ToList()遍历)时,foreach才会逐步执行;
  • 第一个Where的foreach,会在第二个Where遍历它的时候才逐步取原始集合的元素;第二个Where的foreach,则在ToList()遍历它的时候逐步执行。

这种嵌套的迭代执行,最终只会让原始集合被枚举一次,所有过滤逻辑都在这一轮枚举中完成。

内容的提问来源于stack exchange,提问作者jon bee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 01:45:00