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
。Hadx.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;
}