Appropriate GetHashCode() override?

E

Ethan Strauss

Hi,
I have a moderately complex class (about 10 different string and int
type fields along with two different List<string> fields). I want to override
Equals(), so I need to override GetHashCode(). The standard override for
GetHashCode() for something would be to join GetHashCode for each field with
^ (XOR). Right? But, in this case, one of the fields is a "Unique" Identifier
and SHOULD uniquely identify the instance of the class. If that is the case,
is it acceptable to just use the HashCode for that uniqueID field as the
HashCode for the instance? What if there are two different instances with
the same "Unique" identifier, but different contents (which is what I am
looking for with my Equals() override)? If they evaluate to the same HashCode
will that cause major issues?

Thanks!
Ethan
 
L

Lee

Ethan,

There is a great blog entry about this very thing here:
http://blog.roblevine.co.uk/?p=13

But to summarize, if two things are Equal(), there HashCode MUST be
the same and if they are not equal, they CANNOT be the same.

Then again, all this is moot if you never are going to use the class
is a container that uses the HashCode. (Not usually a safe bet due to
possible future enhancements to the codebase)

L. Lee Saunders
http://oldschooldotnet.blogspot.com
 
E

Ethan Strauss

Hi Pete,
Thanks for you comments. In this case, I am populating this class by
pulling data from a database using a WebService. The "Unique" identifier
uniquely identifies a record in the main database table, but I am getting a
bunch of related data as well and I suspicious that I not always getting
exactly the same related data. One of my main goals right now is to see if it
is, in fact, always the same. I guess this means that I don't consider it
unique and should write GetHashCode as though it is not. I will probably go
ahead and rewrite the GetHashCode as described in
http://blog.roblevine.co.uk/?p=19.
By the way, do _not_ composite hash codes using XOR. You will
unnecessarily introduce collisions at a remarkably high rate. The
accepted practice is to use an accumulator, multiplying by a prime number
between each addition of the next field's hash code. Search this
newsgroup for past discussions of hash codes for more details.

Given this (and I now agree with it), Microsoft should really change the
documentation for GetHashCode
(http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx ).
This more or less tells you to just XOR everything together.

Ethan
 
A

Arne Vajhøj

Ethan said:
I have a moderately complex class (about 10 different string and int
type fields along with two different List<string> fields). I want to override
Equals(), so I need to override GetHashCode(). The standard override for
GetHashCode() for something would be to join GetHashCode for each field with
^ (XOR). Right? But, in this case, one of the fields is a "Unique" Identifier
and SHOULD uniquely identify the instance of the class. If that is the case,
is it acceptable to just use the HashCode for that uniqueID field as the
HashCode for the instance?

If the Equals overload just compares those ids, then having HashCode
return the has code of the id is a good solution.
What if there are two different instances with
the same "Unique" identifier, but different contents (which is what I am
looking for with my Equals() override)? If they evaluate to the same HashCode
will that cause major issues?

Having Equals compare other fields than the id and have HashCode return
only the hash code of the id is valid, but in my opinion not good style.

Arne
 
A

Arne Vajhøj

Lee said:
There is a great blog entry about this very thing here:
http://blog.roblevine.co.uk/?p=13

But to summarize, if two things are Equal(), there HashCode MUST be
the same and if they are not equal, they CANNOT be the same.

I hope that your summary are wrong, since in general objects
can return same HashCode even if Equals return false.

Arne
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top