C# Distinct和重写IEqualityComparer时要知道的二三事
作者:新田三十三 发布时间:2023-07-11 15:41:20
我们在想对一个可枚举的对象集合进行去重操作时,一般第一个想到的就是就是Linq的Distinct方法。
先定义一个类,然后使用Distinct方法去重
class Man
{
public int Age { get; set; }
public string Name { get; set; }
public string Adress { get; set; }
public decimal Weight { get; set; }
public decimal Height { get; set; }
}
List<Man> list = new List<Man>()
{
new Man(){Age=21,Name="Adam",Adress="Shenzhen",Weight=60,Height=170},
new Man(){Age=21,Name="Adam",Adress="Shenzhen",Weight=60,Height=170}
};
var distinct = list.Distinct();
然而去重得到的distinct集合的Count依然为二,集合里依然存在两个Adam。
实际上,Distinct方法内进行比较的是声明的引用,而不是对象属性,就和对两个属性一模一样的对象使用Equals()方法得到的是False一样。
因此我们对对象集合使用Distinct方法时要使用重载Distinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer);
要使用这个方法,我们得重写IEqualityComparer接口,再使用Distinct方法:
public class ManComparer : IEqualityComparer<Man>
{
public bool Equals(Man x, Man y)
{
return x.Age == y.Age
&& x.Name == y.Name
&& x.Adress == y.Adress
&& x.Weight == y.Weight
&& x.Height == y.Height;
}
public int GetHashCode(Man obj)
{
return obj.GetHashCode();
}
}
var distinct = list.Distinct(new ManComparer());
然而,再一次,distinct集合内依然有两个对象。
实际上,由于直接获取对象的HashCode,用HashCode进行比较的速度比 Equals 方法更快,
因此IEqualityComparer内部会在使用 Equals 前先使用 GetHashCode 方法,在两个对象的HashCode都相同时即刻判断对象相等。
而当两个对象HashCode不相同时, Equals 方法就会被调用,对要比较的对象进行判断。
由于在上例中list中的两个引用实际上是两个不同的对象,因此HashCode必定不相同
所以要触发Equlas方法,我们需要改 GetHashCode ,让它返回相同的常量
public class ManComparerNew : IEqualityComparer<Man>
{
public bool Equals(Man x, Man y)
{
return x.Age == y.Age
&& x.Name == y.Name
&& x.Adress == y.Adress
&& x.Weight == y.Weight
&& x.Height == y.Height;
}
public int GetHashCode(Man obj)
{
return 1;
}
}
var distinct = list.Distinct(new ManComparerNew());
现在distinct集合中就只有一个Man对象了,成功实现了去重。
来源:https://www.cnblogs.com/mirageJ/p/8950842.html


猜你喜欢
- 一、Nuget安装log4net --> Install-Package log4net二、在AssemblyInfo.cs文件中添加
- DateTime dt = DateTime.Now;Label1.Text = dt.ToString();//2005-11-5 13:
- 本文研究的主要是Java编程Nashorn的相关内容,具体如下。Nashorn是什么Nashorn,发音“nass-horn”,是德国二战时
- 这篇文章主要介绍了简单了解Spring中BeanFactory与FactoryBean的区别,文中通过示例代码介绍的非常详细,对大家的学习或
- List接口是Collection接口的子接口,List有一个重要的实现类--ArrayList类,List中的元素是有序排列的而且可重复,
- 本文实例为大家分享了Android实现竖直跑马灯效果的具体代码,供大家参考,具体内容如下首先给出跑马灯效果图中间的色块是因为视频转成GIF造
- Android 仿今日头条评论时键盘自动弹出的效果:当点击评论时,弹出对话框,同时弹出软键盘,当点击返回键时,将对话框关闭,不只是关闭软键盘
- Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,是一种比较常用
- 本文实例为大家分享了C#实现订单管理程序的具体代码,供大家参考,具体内容如下订单管理的控制台程序,能够实现添加订单、删除订单、修改订单、查询
- 近日工程中,逐渐感觉到原来复制粘贴代码的笨重,突然想起以前有人和我说起过Git和SVN之类的版本管理工具。由于平时主要是写Java代码,所以
- 这是入门的第三天了,从简单的hello spring开始,已经慢慢接近web的样子。接下来当然是读取简单的对象属性了。于是按照网上各位大神教
- 概述HashTable是jdk 1.0中引入的产物,基本上现在很少使用了,但是会在面试中经常被问到,你都知道吗:HashTable底层的实现
- 本文实例讲述了Android开发实现模仿微信小窗口功能。分享给大家供大家参考,具体如下:运用方法:将显示窗口的风格 设置为对话框风格即可具体
- 本文实例讲述了C#静态构造函数用法。分享给大家供大家参考。具体如下:当我们想初始化一些静态变量的时候,就需要用到静态构造函数了。这个静态构造
- Android中的ListView应该算是布局中几种最常用的组件之一了,使用也十分方便,下面将介绍ListView几种比较常见的优化方法:首
- MyEclipse配置IDEA配置Tomcat环境IDEA:2020.2Tomcat:apache-tomcat-9.0.38创建Web项目
- 1. 拷贝 Mybatis 反向工程配置文件到项目的根目录下2. 根据项目及表的情况,修改 GeneratorMapper.xml 配置如果
- 请停止代码注释“干净的代码应该像写好的散文一样” - Robert C. Martin不良代码的通病就是有很多注释。这是凌乱的源代码最明显的
- 这次是列表滑动删除的第三波,仿微信的列表滑动删除。先上个效果图: 前面的文章里面说过开源框架SwipeListView
- 1.导入System.Runtime.InteropServices命名空间。2.API函数ShowWindow()能够控制人和窗体的现实状