c# list 去重的方法
发布时间 - 2025-12-27 00:00:00 点击率:次Distinct()去重需确保类型正确实现Equals和GetHashCode;值类型和已重载的引用类型(如string)可直接使用,自定义类必须重写二者;.NET6+推荐DistinctBy()按属性去重;原地去重宜用HashSet配合RemoveAll;忽略大小写需传StringComparer。
用 Distinct() 去重最常用,但要注意类型是否实现 Equals 和 GetHashCode
对值类型(如 int、string)或已重写相等逻辑的引用类型,直接调用 Linq.Distinct() 即可。它底层依赖对象的相等比较机制:
- 没重写时,引用类型默认按内存地址判等,即使内容相同也会保留多份
-
string是特例,虽是引用类型但已重载,所以new List能正确去重{ "a", "a" }.Distinct() - 自定义类必须重写
Equals(object)和GetHashCode(),否则Distinct()无效
var numbers = new List{ 1, 2, 2, 3 }; var unique = numbers.Distinct().ToList(); // [1, 2, 3]
按指定属性去重要用 DistinctBy()(.NET 6+)或自定义 IEqualityComparer
常见需求是“按 Id 或 Name 去重”,Distinct() 本身不支持投影。.NET 6 引入了 DistinctBy(),简洁安全:
-
DistinctBy(x => x.Id)会保留第一个出现的Id对应项,后续同Id的跳过 - 低版本需手写
IEqualityComparer,容易漏掉GetHashCode实现,导致哈希表行为异常 - 避免用
GroupBy(x => x.Id).Select(g => g.First())—— 性能差,且语义不如DistinctBy清晰
var users = new List{ new User { Id = 1, Name = "Alice" }, new User { Id = 1, Name = "Bob" }, new User { Id = 2, Name = "Charlie" } }; var uniqueById = users.DistinctBy(u => u.Id).ToList(); // 保留 Id=1 的第一个(Alice)
原地去重用 HashSet 配合 RemoveAll() 或重建列表
Distinct() 返回新集合,若需修改原 List,不能直接赋值(会丢失引用)。稳妥做法是清空后重新填充:
- 用
HashSet判断重复最高效(O(1) 查找),比嵌套循环或Contains快得多 - 对引用类型,仍要确保
T的相等逻辑正确,否则HashSet也失效 - 别用
for循环边遍历边删 —— 容易跳过元素或索引越界
var list = new List{ "x", "y", "x", "z" }; var seen = new HashSet (); list.RemoveAll(item => !seen.Add(item)); // seen.Add 返回 true 表示首次加入
字符串忽略大小写的去重必须传 StringComparer
Distinct() 默认区分大小写,"A" 和 "a" 被视为不同。强行转小写再比较(如 Select(x => x.ToLower()).Distinct())会丢失原始大小写形式:
- 用
Distinct(StringComparer.OrdinalIgnoreCase)既去重又保留原字符串 -
StringComparer.CurrentCultureIgnoreCase更适合本地化场景,但性能略低 - 别在
DistinctBy里用x.Name.ToLower()做 key —— 同样丢失原始值,且无法处理null
var words = new List实际用哪一种,取决于你手上的数据类型、.NET 版本、是否需要保留原列表引用,以及“重复”的定义粒度——是整个对象相等,还是某个字段一致。最容易被忽略的是自定义类没重写{ "Apple", "apple", "Banana", "BANANA" }; var unique = words.Distinct(StringComparer.OrdinalIgnoreCase).ToList(); // ["Apple", "Banana"]
GetHashCode,结果 Distinct() 或 HashSet 表现诡异,调试时得回头检查这一条。
# word
# app
# ai
# apple
# 本地化
# c#
# .net
# 数据类型
# String
# Object
# NULL
# for
# select
# 字符串
# int
# 循环
# 值类型
# 引用类型
# 对象
# linq
# 重写
# 自定义
# 第一个
# 跳过
# 的是
# 这一
# 也会
# 首次
# 遍历
# 要用
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在宝塔面板中修改默认建站目录?
Laravel如何创建自定义Facades?(详细步骤)
Laravel怎么实现微信登录_Laravel Socialite第三方登录集成
如何用PHP工具快速搭建高效网站?
网站制作软件有哪些,制图软件有哪些?
linux写shell需要注意的问题(必看)
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?
JavaScript如何实现错误处理_try...catch如何捕获异常?
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)
轻松掌握MySQL函数中的last_insert_id()
佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】
如何快速辨别茅台真假?关键步骤解析
Laravel如何处理表单验证?(Requests代码示例)
宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程
制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?
如何快速搭建高效香港服务器网站?
北京网站制作公司哪家好一点,北京租房网站有哪些?
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
Android利用动画实现背景逐渐变暗
如何用腾讯建站主机快速创建免费网站?
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
如何破解联通资金短缺导致的基站建设难题?
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】
Laravel如何自定义错误页面(404, 500)?(代码示例)
如何快速使用云服务器搭建个人网站?
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
手机网站制作与建设方案,手机网站如何建设?
,网页ppt怎么弄成自己的ppt?
宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
非常酷的网站设计制作软件,酷培ai教育官方网站?
浅谈javascript alert和confirm的美化
如何在企业微信快速生成手机电脑官网?
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
Laravel怎么判断请求类型_Laravel Request isMethod用法
微信小程序 scroll-view组件实现列表页实例代码
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
Laravel如何实现事件和监听器?(Event & Listener实战)
Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)
Firefox Developer Edition开发者版本入口
google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤
高防网站服务器:DDoS防御与BGP线路的AI智能防护方案
制作电商网页,电商供应链怎么做?


ashCode;值类型和已重载的引用类型(如string)可直接使用,自定义类必须重写二者;.NET6+推荐DistinctBy()按属性去重;原地去重宜用HashSet配合RemoveAll;忽略大小写需传StringComparer。