在C#中,
List<t></t>去重最常用、最简洁的方式是用
Distinct()方法(需引用
System.Linq),但它返回的是
IEnumerable<t></t>,如需仍为
List<t></t>,记得调用
ToList()。
用 Distinct() 快速去重(推荐)
适用于值类型(如
int、
string)或已实现
IEquatable<t></t>/ 重写
Equals和
GetHashCode的引用类型。 基础写法:
var uniqueList = list.Distinct().ToList();
string列表忽略大小写去重:
list.Distinct(StringComparer.OrdinalIgnoreCase).ToList()自定义比较:可传入实现
IEqualityComparer<t></t>的类,控制“重复”的判断逻辑
对引用类型按指定属性去重
比如
List<person></person>想按
Name去重,不能直接用
Distinct()(默认比引用)。可用
GroupBy或自定义比较器: 用
GroupBy取每组第一个:
list.GroupBy(x => x.Name).Select(g => g.First()).ToList()更高效方式(避免分组开销):用
DistinctBy(.NET 6+):
list.DistinctBy(x => x.Name).ToList()
原地去重(不创建新列表)
如果必须复用原列表对象(如因外部引用或性能敏感),可用循环 +
RemoveAll或反向遍历移除: 简单但注意顺序:
for (int i = list.Count - 1; i >= 0; i--) { if (list.Take(i).Contains(list[i])) list.RemoveAt(i); }(效率低,仅小数据适用)
推荐原地方案:先转 HashSet 记录已见项,再用 RemoveAll配合标记:
var seen = new HashSet
list.RemoveAll(item => !seen.Add(item));
(
Add返回
true表示首次添加,所以取反即为“重复项”)
注意事项和常见坑
去重结果依赖类型的相等语义:
string默认区分大小写;数值类型无问题 自定义类不去重?大概率没重写
Equals和
GetHashCode,或没传正确比较器
Distinct()不改变原列表顺序,保留首次出现的元素 大数据量慎用
Contains或嵌套循环,优先选哈希类方法(
Distinct、
HashSet)
基本上就这些。日常开发中,90% 场景用
Distinct().ToList()或
DistinctBy()就够了,清晰又高效。
