GetHashCode override

  • Thread starter Bill Mittenzwey
  • Start date
B

Bill Mittenzwey

Ok, I've read in the docs, some books and some articles by prominant
dotneters about how to override GetHashCode, but it still leaves me somewhat
puzzled.

I have a custom object which I want to be able to have sorted correctly in a
sortedlist/hashtable... For that to work correctly, I need to override
Equals(). Fair enough, otherwise the sort would not really know what
represents the value of my object. Then the compiler tells me that I need to
also override the GetHashCode. At first thought, it seems easy, just pass
the call on to my describing property ( a stirng) and it would seem to work.

Ah, but that seems to break the rules for GetHashCode. As I see it, I need
to guarantee that all objects which represent the same value return the same
Hash Code (fine so far), and I need to guarantee that once an object has
supplied a hash code, it will never change. Conflicts start here. What if I
have two objects which have there properties set to two different values,
and so have reported back two different hash values. Then a program changes
the property of one of the objects to be the same as the other. Now I have
two objects which represent the same value, but with two different hash
codes. I seem to be stuck in a catch-22 here. I have to have all objects
representing the same value return the same hash, but I can't change the
hash to make a changed object compliant. What if the objects I wanted to
sort were based off of a property like priority. It is reasonable to have
multiple objects with the same priority in a list, and I would want the
objects to be sorted in the list based off the priority. Also it is common
for a priority to change, in which case, I would want that object to move to
a different location in the list.

Can anyone explain this? Am I just misusing the lists?
 
J

Jon Skeet [C# MVP]

Bill Mittenzwey said:
Ok, I've read in the docs, some books and some articles by prominant
dotneters about how to override GetHashCode, but it still leaves me somewhat
puzzled.

I have a custom object which I want to be able to have sorted correctly in a
sortedlist/hashtable... For that to work correctly, I need to override
Equals(). Fair enough, otherwise the sort would not really know what
represents the value of my object. Then the compiler tells me that I need to
also override the GetHashCode. At first thought, it seems easy, just pass
the call on to my describing property ( a stirng) and it would seem to work.
Yup.

Ah, but that seems to break the rules for GetHashCode. As I see it, I need
to guarantee that all objects which represent the same value return the same
Hash Code (fine so far), and I need to guarantee that once an object has
supplied a hash code, it will never change. Conflicts start here. What if I
have two objects which have there properties set to two different values,
and so have reported back two different hash values. Then a program changes
the property of one of the objects to be the same as the other. Now I have
two objects which represent the same value, but with two different hash
codes.

As soon as types are mutable, you've got a problem whenever they're
stored in hash tables, sorted lists or whatever. Don't forget that
Equals will suddenly change as well - something that *was* Equal to
another thing possibly won't be any more.

Do you *definitely* need your property to be settable?
 
B

Bill Mittenzwey

After some thought, I would consider making that particular class a one-time
write class, but what of the situation I mentioned in the first message,
what you want to sort on is a priority of importance of tasks or something
where the priority is subject to change?
 
G

Guinness Mann

...but what of the situation I mentioned in the first message,
what you want to sort on is a priority of importance of tasks
or something where the priority is subject to change?

Then a hash table is probably not your best container, but be that as it
may, why not pull the item out of the list, change the priority and re-
insert it?

-- Rick
 
J

Jon Skeet [C# MVP]

Bill Mittenzwey said:
After some thought, I would consider making that particular class a one-time
write class

Right - in which case, it would be best to put that one-time-write in
the constructor, or *very carefully* document that it should be set
*before* putting it in a hash table etc.
but what of the situation I mentioned in the first message,
what you want to sort on is a priority of importance of tasks or something
where the priority is subject to change?

Then I wouldn't make the priority part of the equality contract, I
suspect. I very rarely override Equals.
 

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