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
If you want to force the execution of the Equals you can implement it as follows
public int GetHashCode(FactorPayoffs obj) {
return 1;
}
GetHashCode
is intended as a fast but rough estimate of equality, so many operations potentially involving large numbers of comparisons start by checking this result instead of Equals
, and only use Equals
when necessary. In particular, if x.GetHashCode()!=y.GetHashCode()
, then we already know x.Equals(y)
is false, so there is no reason to call Equals
. Had x.GetHashCode()==y.GetHashCode()
, then x
might equal y
, but only a call to Equals
will give a definite answer.
If you implement GetHashCode
in a way that causes GetHashCode
to be different for two objects where Equals
returns true
, then you have a bug in your code and many collection classes and algorithms relying on these methods will silently fail.
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).
Rewrite you GetHashCode
implementation like this, to match the semantics of your Equals
implementation.
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;
}
}
Note, you should use unchecked
because you don't care about overflows. Additionaly, coalescing to string.Empty
is pointlessy wasteful, just exclude from the hash.
See here for the best generic answer I know,