在C#语言中,对集合的条件查询、分组统计等操作使用LINQ非常方便,LINQ的语法格式与SQL非常相似和便捷,而LINQ扩展方法配合Lambda更为简洁,如All、Any、Count、MaxEnumerable类扩展方法,其中Distinct、Intersect、Contains等大量方法中使用了IEqualityComparer<>接口,以实现对象的比较,先看一个查询两个集合交集的代码示例:

public class Product
{
public string Name { get; set; }
public int Code { get; set; }
} // 产品类的自定义比较器
class ProductComparer : IEqualityComparer<Product>
{
// 实现接口`Equals`方法
public bool Equals(Product x, Product y)
{
// 比较两个对象的内存地址是否一致
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
return false;
return x.Code == y.Code && x.Name == y.Name;
} // 实现接口`GetHashCode`方法
public int GetHashCode(Product product)
{
if (Object.ReferenceEquals(product, null)) return 0;
int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();
int hashProductCode = product.Code.GetHashCode();
return hashProductName ^ hashProductCode;
}
} static void Main(string[] args)
{
// 初始化集合数据
Product[] store1 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 } };
Product[] store2 = { new Product { Name = "apple", Code = 9 },
new Product { Name = "lemon", Code = 12 } }; // 查询store1与store2的交集
IEnumerable<Product> duplicates = store1.Intersect(store2, new ProductComparer()); foreach (var product in duplicates)
Console.WriteLine(product.Name + " " + product.Code);
} /*
代码输出结果: apple 9
*/

看了以上代码后,有的小伙伴会问了,为什么要实现IEqualityComparer<>接口?实现IEqualityComparer<>接口需要注意什么?我来为大家解惑

1. 为什么要实现IEqualityComparer<>接口

是为了复杂类型(类)对象的比较,虽然store1[0]store2[0]的属性值都一样,但它们是两个不同的对象,如果GetHashCode方法代码如下,则结果为空。

public int GetHashCode(Product product)
{
return product.GetHashCode();
}

2. 如何实现IEqualityComparer<>接口

首先,我们需要了解IEqualityComparer<>接口的两个方法的作用和逻辑,.NET处理时先比较两个对象GetHashCode方法返回的哈希值是否相等,如果不相等则直接返回,不再执行Equals方法,如果哈希值相等则执行Equals方法继续比较!为什么要用两个方法去对比呢?原因是GetHashCode方法比Equals方法效率更高,所以先执行GetHashCode方法。依据上述分析,把示例中GetHashCode方法改为如下代码,则结果是相同的。

public int GetHashCode(Product product)
{
return 0;
}

C# LINQ之IEqualityComparer<>接口应用的更多相关文章

  1. c# 利用IEqualityComparer接口去除DataTable重复数据

    IEqualityComparer主要适用于定义方法以支持对象的相等比较.可以实现集合的自定义相等比较.即,您可以创建自己的相等定义,并指定此定义与接受 IEqualityComparer 接口的集合 ...

  2. Linq去重 不用实现IEqualityComparer接口的方法超级简单

    RskFactorRelation.Instance.GetCache<RskFactorRelation>(true).Where(x => !string.IsNullOrEmp ...

  3. Linq之IQueryable接口与IEnumberable区别

    IEnumerable接口 公开枚举器,该枚举器支持在指定类型的集合上进行简单迭代.也就是说:实现了此接口的object,就可以直接使用foreach遍历此object: IEnumerable 包含 ...

  4. 用泛型的IEqualityComparer<T>接口去重复项

    提供者:porschev 题目:下列数据放在一个List中,当ID和Name都相同时,去掉重复数据 ID Name 1  张三 1  李三 1  小伟 1  李三  2  李四 2  李武 ----- ...

  5. linq distinct 不够用了!

    问题引出:在实际中遇到一个问题,要进行集合去重,集合内存储的是引用类型,需要根据id进行去重.这个时候linq 的distinct 就不够用了,对于引用类型,它直接比较地址.测试数据如下: class ...

  6. 《LINQ技术详解C#》-4.LINQ到对象

    public static string[] Presidents { get; } = { "Adams", "Arthur", "Buchanan ...

  7. linq操作符:限定操作符

    限定操作符运算返回一个Boolean值,该值指示序列中是否有一些元素满足条件或者是否所有元素都满足条件. 一.All操作符 All方法用来确定是否序列中的所有元素都满足条件.看下面的例子: using ...

  8. Linq之Distinct详解

    前天在做批量数据导入新增时,要对数据进行有效性判断,其中还要去除重复,如果没出现linq的话可能会新声明一个临时对象集合,然后遍历原始数据判断把符合条件的数据添加到临时集合中,这在有了linq之后显得 ...

  9. IEqualityComparer的使用

    当我们用Linq操作我们自定义的对像数组时,我们会发现有些方法直接使用的话根本不起作用,比如:Distinct.Except.Intersect等扩展方法. 对于我们自定义的对象的比较,我们必须实现I ...

  10. LINQ 方法

    过滤操作符 Where 运算符(Linq扩展方法)根据给定条件过滤集合. 在其中扩展方法有以下两个重载.一个过载需要Func <TSource,bool>输入参数和第二个重载方法需要Fun ...

随机推荐

  1. C# 借助NPOI 完成 xls 转换为xlsx

    背景:MinExcel开源类库,导数据的库,占用内存很低,通过io,不通过内存保存,不支持 xls格式的文件,支持csv和xlsx,所以要想使用这个库,就得把xls格式转换为xlsx.只复制了数据 合 ...

  2. C# XML转Json Json转XML XML 转对象 对象转XML

    对象转XML对象时,只能是一个JObject对象,不能是一个集合对象.如果对象是一个列表集合,需要定义一个根对象比如这样:var obj =new { Root = ListLogs[ListLogs ...

  3. .NETCore Nuget 发布包含静态文件 content file

    .NETCore 在.csproj引用资源中标记pack配置 <pack>true</pack>1例如 <ItemGroup> <Content Includ ...

  4. firewall防火墙基础配置

    Firewalld防火墙 Centos7 中集成了防火墙管理工具, Firewall系统动态防火墙管理器是作为默认的防火墙工具. 它支持规则动态更新,并加入zone区域概念. Firewalld防火墙 ...

  5. Java爬虫-爬取疫苗批次信息

    今年3月份开始,就接到通知, 根据<关于开展有关人群第二剂次脊髓灰质炎灭活疫苗补种工作的通知>国疾控卫免发[2024]1号文件要求,在2016年3月1日至2019年9月30日之间出生的儿童 ...

  6. ajax兼容处理

     // ajax的兼容处理         // 1.创建ajax对象         // 标准浏览器         // const xhr = new XMLHttpRequest();    ...

  7. 程序员面试金典-面试题 01.03. URL化

    题目: URL化.编写一种方法,将字符串中的空格全部替换为%20.假定该字符串尾部有足够的空间存放新增字符,并且知道字符串的"真实"长度.(注:用Java实现的话,请使用字符数组实 ...

  8. 【Java面试题-基础知识01】Java数据类型四连问?

    一.Java中的基础数据类型有哪些? Java中的基本数据类型包括: 1. byte:8位有符号整数,范围为-128到127.2. short:16位有符号整数,范围为-32768到32767.3. ...

  9. Mysql主机环境导入导出数据

    mysql数据库,在主机环境下导出数据为csv文件. 命令:select * into outfile '/mysql/11.csv' from 表; 可能会报错:ERROR 1290 (HY000) ...

  10. 内部网关协议RIP-路由选择协议

    路由信息协议RIP(Routing Information Protocol)是内部网关协议IGP中最先得到广泛使用的协议,其相关标准文档为RFC1058. 一.RIP基本工作原理 RIP要求自治系统 ...