You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 06:10:31