C# 正在调用IEqualityComparer GetHashCode,但不等于

C# 正在调用IEqualityComparer GetHashCode,但不等于,c#,C#,我有两个列表要比较。因此,我创建了一个实现IEqualityComparer接口的类,请参见下面代码底部的部分 当我单步执行代码时,代码将执行我的GetHashCode实现,而不是Equals?我并不真正理解GetHashCode方法,尽管我在互联网上读过很多东西,知道它到底在做什么 List<FactorPayoffs> missingfactorPayoffList = factorPayoffList.Except( factorPayoffListO

我有两个列表要比较。因此,我创建了一个实现
IEqualityComparer
接口的类,请参见下面代码底部的部分

当我单步执行代码时,代码将执行我的
GetHashCode
实现,而不是
Equals
?我并不真正理解
GetHashCode
方法,尽管我在互联网上读过很多东西,知道它到底在做什么

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

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

您的
Equals
GetHashCode
实现应该包含完全相同的属性集;他们没有

在更正式的术语中,
GetHashCode
必须始终为比较相等的两个对象返回相同的值。对于当前代码,两个仅在
Ret_USD
值上不同的对象将始终进行相等比较,但不能保证具有相同的哈希代码

<> P>这样,LINQ在两个对象相等的情况下调用<代码> GetHashCode <代码>,返回不同的值,得出结论:由于值不同,对象不能相等,所以调用<代码>等于< < /代码>没有任何意义,继续前进。


要解决此问题,请从
GetHashCode
中删除
Ret_USD
因子,或者在
Equals
中引入该因子(对等式语义有意义的任何内容)。

GetHashCode
旨在快速但粗略地估计等式,因此,许多可能涉及大量比较的操作都是从检查此结果开始的,而不是从检查
Equals
,并且仅在必要时使用
Equals
。特别是,如果
x.GetHashCode()=y、 GetHashCode()
,那么我们已经知道
x.Equals(y)
为false,所以没有理由调用
Equals
。Had
x.GetHashCode()==y.GetHashCode()
,则
x
可能等于
y
,但只有调用
Equals
才能给出明确的答案


如果实现
GetHashCode
的方式导致
GetHashCode
对于
等于
的两个对象不同,则返回
true
,然后您的代码中有一个bug,许多依赖于这些方法的集合类和算法将自动失败。

像这样重写您的
GetHashCode
实现,以匹配
Equals
实现的语义

public int GetHashCode(FactorPayoffs obj)
{
    unchecked
    {
            int hash = 17;
            hash = hash * 23 + obj.dtPrice.GetHashCode();
            hash = hash * 23 + obj.dtPrice_e.GetHashCode();
            if (obj.Factor != null)
            {
                hash = hash * 23 + obj.Factor.GetHashCode();
            }

            if (obj.FactorGroup != null)
            {
                hash = hash * 23 + obj.FactorGroup.GetHashCode();
            }

            return hash;
    }
}
注意,您应该使用未选中的
,因为您不关心溢出。另外,合并到
string.Empty
是毫无意义的浪费,只需从哈希中排除即可


请参阅,

如果要强制执行Equals,可以按如下方式实现它

public int GetHashCode(FactorPayoffs obj) {
        return 1;
    }

当两个实例被认为相等时,
GetHashCode
实现必须返回相同的值。当它们不相等时,它应该尝试返回不同的数字,但这不太重要。谢谢-它现在可以工作了。我想我需要阅读更多关于hashcode的内容,我不理解它们是如何被使用的generated@mHelpMe@mHelpMe,aslo,算术应该被取消选中,并避免无意义的空合并,
public int GetHashCode(FactorPayoffs obj) {
        return 1;
    }