如何在.NET Framework 4.8下高效将List按条件拆分为两个列表
优化思路
- 核心优化点是将原方案两次遍历集合的逻辑改为单次遍历,既避免了重复执行条件判断,也省去了LINQ两次延迟执行带来的额外开销,性能提升逻辑明确。
- 可以封装为通用扩展方法,适配所有
IEnumerable<T>类型的集合,完全兼容.NET Framework 4.8运行环境。
实现代码
C# 7.0+ 元组返回版本(推荐)
using System; using System.Collections.Generic; public static class EnumerableExtensions { public static (List<T> Matched, List<T> Unmatched) SplitByCondition<T>(this IEnumerable<T> source, Func<T, bool> predicate) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); var matched = new List<T>(); var unmatched = new List<T>(); foreach (var item in source) { if (predicate(item)) { matched.Add(item); } else { unmatched.Add(item); } } return (matched, unmatched); } }
调用方式:
// 假设yourList是你要拆分的原始列表 var (listTrue, listFalse) = yourList.SplitByCondition(x => x.condition());
低版本C#兼容版本(out参数实现)
如果项目C#版本低于7.0不支持元组语法,可以使用该版本:
using System; using System.Collections.Generic; public static class EnumerableExtensions { public static void SplitByCondition<T>(this IEnumerable<T> source, Func<T, bool> predicate, out List<T> matched, out List<T> unmatched) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); matched = new List<T>(); unmatched = new List<T>(); foreach (var item in source) { if (predicate(item)) { matched.Add(item); } else { unmatched.Add(item); } } } }
调用方式:
List<YourType> listTrue, listFalse; yourList.SplitByCondition(x => x.condition(), out listTrue, out listFalse);
可选进阶优化
如果原始集合是ICollection<T>类型(比如最常用的List<T>),可以在初始化结果列表时指定容量,避免列表动态扩容的开销,进一步提升性能:
// 在创建matched、unmatched前增加容量初始化逻辑 if (source is ICollection<T> collection) { // 提前分配足够容量,避免扩容拷贝 matched = new List<T>(collection.Count); // 内存充裕的前提下,unmatched也可以指定相同容量,追求极致速度 // unmatched = new List<T>(collection.Count); }
内容的提问来源于stack exchange,提问作者Danil.T
相关产品推荐
相关产品推荐

