在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. RuoYi(若依)前后端分离版本,windows下部署(nginx)

    摘自:https://blog.csdn.net/yueyekkx/article/details/105505490 上一篇用了tomcat部署(https://blog.csdn.net/yuey ...

  2. JSON转化工具的使用

    概述 JSON是一种轻量化的数据传输格式,在各种场景都有运用.比如在ajax中,服务端的数据一般通过JSON字符串的格式传输给前端,前端ajax引擎自动将JSON字符串转化为JS对象(需要将ajax的 ...

  3. Android 13 - Media框架(31)- ACodec(七)

    关注公众号免费阅读全文,进入音视频开发技术分享群! 之前的章节中我们解了 input buffer 是如何传递给 OMX 的,以及Output buffer 是如何分配并且注册给 OMX 的.这一节我 ...

  4. Winform程序在VS中打包成安装程序(带卸载)

    场景 在VS中进行Winform开发时,可以直接在项目上右击选择生成 则会在项目的bin目录下直接生成exe等文件,此时将这个文件夹直接整个复制到别的地方就可以运行. 但是如果将其做成安装包安装的形式 ...

  5. 23ai中的True Cache到底能做啥?

    最近,Oracle的产品管理总监在Oracle数据库内幕中介绍了True Cache. 原文链接如下: https://blogs.oracle.com/database/post/introduci ...

  6. Visual Studio 智能代码插件:CodeGeeX

    前言 在软件开发领域,高效的编程助手一直是提升开发者效率和质量的关键.随着人工智能技术的不断发展,智能编程助手逐渐成为开发者们不可或缺的工具.其中,CodeGeeX作为一款专为Visual Studi ...

  7. STM32WB55 BLE双核flash擦写程序深度解析

    简介 STM32WB55的flash擦除有两种机制,一种是只有单核运行下的flash擦除,这种模式下,flash擦除的步骤同其他STM32的flash擦除一样,直接调用HAL库中flash擦除的库函数 ...

  8. IOS Video Tool Box后台解码失败

    ---恢复内容开始--- 1.VideoToolBox硬件解码H264流的过程中,如果App从前台按Home键进入后台,会立马产生一个-12903的错误  如果这个时候重置解码器,继续解码,会遇到 - ...

  9. html2canvas + jspdf导出pdf,文字重叠,样式不显示或者文字不显示

    先在html引入cdn <script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></s ...

  10. The solution of ABC144F

    都不知道什么时候做的题了 problem & blog 一开始很容易想到枚举断边然后 DP 算代价. 于是很容易想到 DP 状态定义:设 \(dp_u\) 为从 \(u\) 出发到 \(n\) ...