的IEqualityComparer的GetHashCode被称作但不等于 [英] IEqualityComparer GetHashCode being called but Equals not

查看:140
本文介绍了的IEqualityComparer的GetHashCode被称作但不等于的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个列表,我试图比较。所以,我创建了一个实现了的IEqualityComparer 接口的类,请参见下面的代码底部。



当我通过我的执行代码,该代码经过我的的GetHashCode 执行,而不是等于?我真的不明白的GetHashCode 的方法,尽管在互联网上阅读周围,究竟它在做什么。

 列表< FactorPayoffs> missingfactorPayoffList = 
factorPayoffList.Except(
factorPayoffListOrg,
新FactorPayoffs.Comparer())了ToList();

名单,LT; FactorPayoffs> missingfactorPayoffListOrg =
factorPayoffListOrg.Except(
factorPayoffList,
新FactorPayoffs.Comparer())了ToList();



所以在两个列表上面的两行代码返回我的每一个项目,告诉我,这两个列表不包含与相同的任何产品。这是不正确的,则这是唯一的不同的行。我猜这正在发生,因为等于方法不获取调用这反过来使我怀疑我的的GetHashCode ?方法工作作为它应该

 类FactorPayoffs 
{
公共字符串FactorGroup {搞定;组; }
公共字符串因子{搞定;组; }
公众的DateTime dtPrice {搞定;组; }
公众的DateTime dtPrice_e {搞定;组; }
公共双Ret_USD {搞定;组; }

公共类的Comparer:&的IEqualityComparer LT; FactorPayoffs>
{
公共布尔等于(FactorPayoffs X,FactorPayoffs Y)
{
返回x.dtPrice == y.dtPrice&放大器;&安培;
x.dtPrice_e == y.dtPrice_e&放大器;&安培;
x.Factor == y.Factor&放大器;&安培;
x.FactorGroup == y.FactorGroup;
}

公众诠释的GetHashCode(FactorPayoffs OBJ)
{
INT哈希= 17;
哈希散列= * 23 +(obj.dtPrice).GetHashCode();
哈希散列= * 23 +(obj.dtPrice_e).GetHashCode();
哈希散列= * 23 +(obj.Factor ??).GetHashCode();
哈希散列= * 23 +(obj.FactorGroup ??).GetHashCode();
哈希散列= * 23 +(obj.Ret_USD).GetHashCode();
返回哈希;
}
}
}


解决方案

等于的GetHashCode 的实施应涉及完全相同的一组属性;他们不这样做。



在较正式用词,的GetHashCode 必须返回相同对于比较相等的两个对象的价值。根据您当前的代码,区别仅在 Ret_USD 值两个对象总是等于但不保证具有相同的散列码。



那么,什么情况是,LINQ调用的GetHashCode 你认为相等的两个对象,回来价值观不同,结论是,由于该值是不同的对象不能等于所以在调用等于有没有点都和上移动。



要解决该问题,请删除从的GetHashCode Ret_USD 因子或介绍它也在里面等于 (无论适合您的平等语义)。


I have two lists that I am trying to compare. So I have created a class that implements the IEqualityComparer interface, please see below in the bottom section of code.

When I step through my code, the code goes through my GetHashCode implementation but not the Equals? I do not really understand the GetHashCode method, despite reading around on the internet and what exactly it is doing.

List<FactorPayoffs> missingfactorPayoffList = 
    factorPayoffList.Except(
        factorPayoffListOrg,
        new FactorPayoffs.Comparer()).ToList();

List<FactorPayoffs> missingfactorPayoffListOrg =
    factorPayoffListOrg.Except(
        factorPayoffList,
        new FactorPayoffs.Comparer()).ToList();

So in the two lines of code above the two lists return me every item, telling me that the two lists do not contain any items that are the same. This is not true, there is only row that is different. I'm guessing this is happening because the Equals method is not getting called which in turns makes me wonder if my GetHashCode method is working as its supposed to?

class FactorPayoffs
    {
        public string FactorGroup { get; set; }
        public string Factor { get; set; }
        public DateTime dtPrice { get; set; }
        public DateTime dtPrice_e { get; set; }
        public double Ret_USD { get; set; }

        public class Comparer : IEqualityComparer<FactorPayoffs>
        {
            public bool Equals(FactorPayoffs x, FactorPayoffs y)
            {                    
                return x.dtPrice == y.dtPrice && 
                    x.dtPrice_e == y.dtPrice_e && 
                    x.Factor == y.Factor && 
                    x.FactorGroup == y.FactorGroup;
            }

            public int GetHashCode(FactorPayoffs obj)
            {
                int hash = 17;
                hash = hash * 23 + (obj.dtPrice).GetHashCode();
                hash = hash * 23 + (obj.dtPrice_e).GetHashCode();
                hash = hash * 23 + (obj.Factor ?? "").GetHashCode();
                hash = hash * 23 + (obj.FactorGroup ?? "").GetHashCode();
                hash = hash * 23 + (obj.Ret_USD).GetHashCode();
                return hash;
            }
        }
    }

解决方案

Your Equals and GetHashCode implementations should involve the exact same set of properties; they do not.

In more formal terms, GetHashCode must always return the same value for two objects that compare equal. With your current code, two objects that differ only in the Ret_USD value will always compare equal but are not guaranteed to have the same hash code.

So what happens is that LINQ calls GetHashCode on two objects you consider equal, gets back different values, concludes that since the values were different the objects cannot be equal so there's no point at all in calling Equals and moves on.

To fix the problem, either remove the Ret_USD factor from GetHashCode or introduce it also inside Equals (whatever makes sense for your semantics of equality).

这篇关于的IEqualityComparer的GetHashCode被称作但不等于的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆