linq中 List<T>.ForEach() 与 的 Select() 方法区别——CAD c#二次开发

发布于:2025-05-14 ⋅ 阅读:(14) ⋅ 点赞:(0)

1. 核心区别

List<T>.ForEach(Action<T> action)
  • 作用:对列表中的每个元素执行指定操作(副作用),例如修改元素属性。
  • 返回值void(无返回值)。
  • 执行时机:立即执行。
  • 示例
    list.ForEach(item => item.ColorIndex = 1); // 直接修改原列表元素
    Enumerable.Select(Func<T, TResult> selector)
  • 作用:将集合中的每个元素映射为新值,生成一个新的序列。
  • 返回值IEnumerable<TResult>(延迟执行的迭代器)。
  • 执行时机:延迟执行(调用 ToList()foreach 等终端操作时才执行)。
  • 示例
    var newList = list.Select(item => {
        item.ColorIndex = 1; // 修改原元素
        return item;         // 返回修改后的元素(但也可以返回新对象)
    }).ToList();

    2. 是否可以替换?

    场景 1:仅修改原集合元素(无返回值需求)
  • ForEach 更合适,代码更简洁:
    list.ForEach(item => item.ColorIndex = 1); // 直接修改,无返回值
    场景 2:需要生成新集合(保留原集合不变)
  • 必须用 Select,因为 ForEach 无法返回新集合:
  • var newList = list.Select(item => {
        var clone = item.Clone(); // 克隆原对象
        clone.ColorIndex = 1;     // 修改克隆对象
        return clone;             // 返回新对象,原集合不变
    }).ToList();

    3. 关键差异对比表

  • 特性 List<T>.ForEach() Enumerable.Select()
    核心用途 对元素执行副作用(如修改属性) 映射元素生成新集合
    返回值 void(无返回值) IEnumerable<TResult>(新序列)
    是否修改原集合 直接修改原集合元素 不修改原集合(可选择返回新对象)
    延迟执行 立即执行 延迟执行
    链式调用 不支持(返回 void 支持(可继续链式调用其他 LINQ 方法)

 

4. 常见误区

误区 1:认为 Select 不能修改原元素
  • 实际上可以在 Select 中修改原元素,但通常不建议这样做(违背函数式编程原则)。
  • 正确姿势:如果需要保留原集合,应克隆对象后修改:
var newList = list.Select(item => {
    var clone = item.Clone();
    clone.ColorIndex = 1;
    return clone;
}).ToList(); // 原集合不变,新集合包含修改后的克隆对象
误区 2:过度使用 ForEach
  • ForEach 本质是封装的 foreach 循环,适合简单副作用操作。
  • 若需要过滤、聚合或与其他 LINQ 方法链式调用,应优先用 Select

5. 建议用法

  • 用 ForEach 当:需要直接修改原集合元素,且无需生成新集合。
  • 用 Select 当
    • 需要生成新集合(无论是否修改原元素)。
    • 需要与其他 LINQ 方法(如 WhereAggregate)组合使用。

例如,筛选并修改元素:

var filteredPolylines = list
    .OfType<Polyline>() // 筛选Polyline类型(替代Where+类型检查)
    .Select(polyline => {
        var clone = (Polyline)polyline.Clone(); // 克隆对象避免修改原集合
        clone.ColorIndex = 1;                    // 修改克隆对象的颜色
        return clone;                            // 返回修改后的新对象
    })
    .ToList();
var filteredAndModified = list
    .Where(item => item.IsActive)
    .Select(item => {
        item.ColorIndex = 1;
        return item;
    })
    .ToList();

总结

  • ForEach 是命令式的副作用操作,适合直接修改原集合。
  • Select 是声明式的映射操作,适合生成新集合或与其他 LINQ 操作组合。
  • 避免在 Select 中修改原元素,除非你明确需要这样做。

网站公告

今日签到

点亮在社区的每一天
去签到