What would be the best way to override the GetHashCode
function for the case, when
my objects are considered equal if there is at least ONE field match in them.
In the case of generic Equals
method the example might look like this:
public bool Equals(Whatever other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
// Considering that the values can't be 'null' here.
return other.Id.Equals(Id) || Equals(other.Money, Money) ||
Equals(other.Code, Code);
}
Still, I'm confused about making a good GetHashCode
implementation for this case.
How should this be done?
Thank you.
This is a terrible definition of Equals
because it is not transitive.
Consider
x = { Id = 1, Money = 0.1, Code = "X" }
y = { Id = 1, Money = 0.2, Code = "Y" }
z = { Id = 3, Money = 0.2, Code = "Z" }
Then x == y
and y == z
but x != z
.
Additionally, we can establish that the only reasonable implementation of GetHashCode
is a constant map.
Suppose that x
and y
are distinct objects. Let z
be the object
z = { Id = x.Id, Money = y.Money, Code = "Z" }
Then x == z
and y == z
so that x.GetHashCode() == z.GetHashCode()
and y.GetHashCode() == z.GetHashCode()
establishing that x.GetHashCode() == y.GetHashCode()
. Since x
and y
were arbitrary we have established that GetHashCode
is constant.
Thus, we have shown that the only possible implementation of GetHashCode
is
private readonly int constant = 17;
public override int GetHashCode() {
return constant;
}
All of this put together makes it clear that you need to rethink the concept you are trying model, and come up with a different definition of Equals
.