为何List调用Distinct函数后未修改原集合?LINQ函数特性困惑
问题解答
核心原因:两类方法的设计逻辑差异
- LINQ扩展方法(包括
Distinct、OrderBy、Concat)都是非破坏性操作:它们不会修改原集合,而是返回一个全新的、经过处理的序列(IEnumerable<T>类型)。 Sort、AddRange是List<T>自身的实例方法,属于破坏性操作:直接在原集合的内存空间上修改数据,不会返回新集合。
你的代码里Distinct没生效的原因
你调用infos.Distinct()后,只是生成了一个去重后的序列,但既没把这个新序列赋值回原集合,也没直接使用它。原infos列表完全没被改动,所以遍历输出的还是原来的重复数据。
修正代码的两种方式
方式1:将去重结果重新赋值给原列表
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApp6 { class Program { static void Main(string[] args) { string text = Console.ReadLine(); List<string> infos = text.Split(" ").ToList(); // 把Distinct返回的序列转成List,重新赋值给infos infos = infos.Distinct().ToList(); foreach (string info in infos) { Console.Write(info + " "); } } } }
方式2:直接遍历Distinct返回的序列(不修改原列表)
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApp6 { class Program { static void Main(string[] args) { string text = Console.ReadLine(); List<string> infos = text.Split(" ").ToList(); // 直接遍历去重后的序列,原列表保持不变 foreach (string info in infos.Distinct()) { Console.Write(info + " "); } } } }
再明确两类方法的特点
- 修改原集合的方法:都是
List<T>的成员方法,比如Sort、AddRange、Remove、Clear等,这类方法返回值通常是void或操作状态(比如bool),直接作用于原对象。 - 返回新序列的方法:LINQ扩展方法(需引用
System.Linq),比如Distinct、OrderBy、Concat、Where等,返回值是IEnumerable<T>,本质是延迟执行的查询,只有遍历的时候才生成结果,不会改动原集合。
内容的提问来源于stack exchange,提问作者Martin Kulev
相关产品推荐
相关产品推荐

