I had the following code to generate a hash of an object:
public int GetHashCode(MyType obj)
{
return (obj.Prop1.GetHashCode() + obj.Prop2.GetHashCode() + obj.Prop3.GetHashCode()).GetHashCode();
}
I.e. I add all the properties' hash codes and then take the hash of this.
In review, a coworker suggested that this will collide too frequently. I'm not sure that this is true because:
Who is correct?
It is in C#, in case the answer is language-specific.
Yes.
Just suppose Prop1, Prop2 etc are of type int
. Usually only the lower range of integers is used. Your sum approach will collide more often than necessary.
The HasCode of 7
is 7, which makes perfect sense when hashing int
by it self. But with your code the tuples <7, 3>
, <3, 7>
and <8, 2>
will all have the same Hash. The same with simple XOR instead of Addition.
The common approach is to add some (prime) numbers and shifting:
public int GetHashCode(MyType obj)
{
int hash = 0;
unchecked
{
hash += 19 * obj.Prop1.GetHashCode();
hash += 31 * obj.Prop2.GetHashCode();
hash += 37 * obj.Prop3.GetHashCode();
}
return hash;
}
The numbers 19, 31, 37 are not too critical. And if you prefer you can use OR or XOR instead of +
.
XORing would be better:
public int GetHashCode(MyType obj)
{
return obj.Prop1.GetHashCode() ^
obj.Prop2.GetHashCode() ^
obj.Prop3.GetHashCode();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With