C#中IEqualityComparer接口

📅 2026/8/11 11:14:18
C#中IEqualityComparer接口
一、IEqualityComparerT 核心基础接口定义‌它是.NET提供的泛型相等比较接口用于自定义对象的相等判断逻辑默认的引用类型比较是判断内存地址该接口可实现按属性值自定义相等规则。两个必实现方法‌Equals(T x, T y)‌直接判断两个对象是否相等返回布尔值。GetHashCode(T obj)‌为对象生成哈希码若Equals判定两个对象相等二者哈希码必须完全一致否则会引发集合查找异常。二、标准自定义实现示例以自定义Person对象按姓名忽略大小写去重为例public class PersonNameComparer : IEqualityComparerPerson{public bool Equals(Person x, Person y){// 处理空值边界if (x null y null) return true;if (x null || y null) return false;// 按姓名忽略大小写比较return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);}public int GetHashCode(Person obj){if (obj null) return 0;// 哈希码和比较逻辑保持一致基于忽略大小写的姓名生成return obj.Name?.GetHashCode(StringComparison.OrdinalIgnoreCase) ?? 0;}}该实现可直接用于HashSetT、DictionaryTKey,TValue、LINQ的Distinct等集合操作中。三、与LambdaComparer的关联实现为了避免每次自定义相等规则都要新建一个独立类可封装通用的LambdaComparer类直接通过Lambda表达式传入比较逻辑实现接口的灵活复用public class LambdaComparerT : IEqualityComparerT{private readonly FuncT, T, bool _equalsFunc;private readonly FuncT, int _hashFunc;public LambdaComparer(FuncT, T, bool equalsFunc, FuncT, int hashFunc){_equalsFunc equalsFunc ?? throw new ArgumentNullException(nameof(equalsFunc));_hashFunc hashFunc ?? throw new ArgumentNullException(nameof(hashFunc));}public bool Equals(T x, T y) _equalsFunc(x, y);public int GetHashCode(T obj) _hashFunc(obj);}使用时无需新建类直接传入Lambda即可完成去重操作csharpvar newList list.Distinct(new LambdaComparerUser((a, b) a.Id b.Id,obj obj.Id.GetHashCode())).ToList();大幅简化了自定义相等比较的代码量。四、常见使用场景LINQ集合操作‌为Distinct、Union、Intersect、Except等方法传入自定义比较规则实现引用类型按属性去重、求交集等操作。集合容器适配‌作为HashSetT、DictionaryTKey,TValue的构造参数自定义键的相等判断逻辑实现复杂对象作为字典键的场景。五、关键避坑要点必须保证Equals和GetHashCode的逻辑完全一致若两个对象Equals返回true哈希码必须相同否则会出现哈希冲突、集合查找失败的问题。必须显式处理null值避免空引用异常保证比较逻辑的健壮性。哈希码的分布要尽可能均匀减少哈希冲突提升集合查找的性能.NET Core 3.0可使用HashCode.Combine简化哈希码生成。