为何IEqualityComparer未按预期工作?自定义MyEqComp异常排查
自定义EqualityComparer实现异常问题
自定义的MyEqComp类无法正常工作:原本期望arr中仅保留Value为"456"的myDic["1"]和myDic["3"]两个元素,但实际结果却是Value不相等的myDic["1"]和myDic["2"]。另外,第一个和第三个元素的GetHashCode方法返回了相同的哈希码!
代码示例
public class Program { public static Dictionary<string,string> myDic = new Dictionary<string,string>(); public static void Main() { myDic.Add("1","456"); myDic.Add("2","567"); myDic.Add("3","456"); var arr=myDic.Distinct(new MyEqComp()); foreach (var n in arr) { Console.WriteLine("key="+n.Key+",value="+n.Value+"\n"); } } class MyEqComp:IEqualityComparer<KeyValuePair<string,string>>{ public bool Equals(KeyValuePair<string,string> pair1, KeyValuePair<string,string> pair2){ Console.WriteLine("pair1="+pair1+",pair2="+pair2); return pair1.Value == pair2.Value; } public int GetHashCode(KeyValuePair<string,string> pair){ var code = pair.Value.GetHashCode(); Console.WriteLine("code="+code); return code; } } }
程序输出
code=-121858068 key=1,value=456 code=437991364 key=2,value=567 code=-121858068 pair1=[1, 456],pair2=[3, 456]
问题分析与解决
核心误解
你混淆了Distinct和Where的作用:
Distinct是去重,即序列中每个重复元素只保留第一个出现的实例;Where才是筛选,用来保留符合指定条件的所有元素。
你的MyEqComp实现本身是正确的:它按KeyValuePair的Value判断相等性,所以Distinct会保留第一个"456"(key=1)和第一个"567"(key=2),第三个元素key=3的Value和key=1相同,经哈希码比对和Equals判断后被判定为重复,因此被排除,这完全符合Distinct的设计逻辑。
至于哈希码相同的问题:因为key=1和key=3的Value都是"456",string.GetHashCode()对相同字符串返回相同哈希值是正常的——这是IEqualityComparer的规范要求:相等的对象必须返回相同的哈希码。
修正方案
如果你的需求是保留所有Value为"456"的元素,直接用Where替换Distinct:
var arr = myDic.Where(p => p.Value == "456");
如果你的需求是按Value去重(每个Value只留第一个出现的元素),那么当前代码的输出就是正确结果,无需修改MyEqComp。
内容的提问来源于stack exchange,提问作者NoImagination
相关产品推荐
相关产品推荐

