C#中移除List元素并返回新列表且原列表不变的最优方法
C# 不修改原列表移除指定元素并返回新列表的实现方案
原生 List<T> 的 Remove() 方法是直接修改原列表、返回布尔值表示是否删除成功,并没有提供你需要的返回新列表的重载,以下是两种常见场景的最优实现:
场景1:移除所有匹配指定值的元素
日常开发优先选这种写法,基于LINQ实现,代码最简洁,框架底层已经做了性能优化,绝大多数场景下性能足够:
// 需要先引用命名空间 System.Linq List<int> a = new List<int> {1, 2, 3, 3}; // 过滤掉所有等于3的元素,生成新列表 List<int> b = a.Where(x => x != 3).ToList();
执行后原列表 a 内容完全不变,b 的值为 {1,2}。
场景2:仅移除第一个匹配的元素(和原生Remove行为一致)
如果你需要和原生 Remove() 保持同样的逻辑,只删除第一个出现的目标元素,可以封装扩展方法实现,大列表下性能比「先拷贝全列表再删元素」的写法更高:
public static class ListExtensions { public static List<T> RemoveWithoutModify<T>(this List<T> source, T target) { if (source == null) throw new ArgumentNullException(nameof(source)); int matchIndex = source.IndexOf(target); // 没有匹配元素直接返回原列表的拷贝 if (matchIndex < 0) return new List<T>(source); // 拆分拷贝前后段,避免删除元素带来的数组移位开销 var result = new List<T>(source.Count - 1); result.AddRange(source.GetRange(0, matchIndex)); result.AddRange(source.GetRange(matchIndex + 1, source.Count - matchIndex - 1)); return result; } }
调用方式和你示例中的写法一致:
List<int> a = new List<int> {1, 2, 3}; List<int> b = a.RemoveWithoutModify(3);
注意事项
如果存储的是引用类型元素,默认会按引用比较是否匹配,需要自定义比较规则的话可以直接在 Where 条件里修改判断逻辑,或者给 IndexOf 方法传入自定义比较器。
内容的提问来源于stack exchange,提问作者Tien Dang
相关产品推荐
相关产品推荐

