-1

I've read that an object's hashcode should not change while it is part of a Dictionary. Because if it changed, there would be no way to find it in the Dictionary.

Why doesn't the Dictionary class have logic to move an object to the correct bucket when it detects that the object's hashcode has changed?

3
  • 1
    // when it detects that the object's hashcode has changed // is easier said than done. (Here, it is assumed that changing the object automatically triggers a remove-reinsert with the dictionary, which means the object has a reference to the dictionary as well.) In fact, this is what Entity Framework does. People later found that it is "scalable" to a small number of items ... If you have a good solution, I would encourage you to apply to the company
    – rwong
    May 1, 2018 at 6:47
  • 1
    Why would you want to change the hashcode of an item? That doesn't make sense, outside of contrived scenarios.
    – Josh
    May 1, 2018 at 19:35
  • Why does my question have -1, but the accepted answer has 8? May 2, 2018 at 4:09

4 Answers 4

8

Why doesn't the Dictionary class have logic to move an object to the correct bucket when it detects that the object's hashcode has changed?

Just to be sure, we are talking about the hash of the key here, the hash of the value is irrelevant.

The important part of your comment is: [...] when it detects that the object's hashcode has changed. ...but how?

  • Continuously iterating over all entries in the dictionary would be both inefficient and not thread safe.
  • The other option would that for each possible key, you should add a a listener's mechanism to trigger an event when the key's value/hashcode changes. That would really be a PITA and inefficient too.

Since it's pretty rare that you have to modify keys within your dictionary, it's by far easier and more efficient to remove the entry with the old key and add it back with the new key.

1
  • 3
    If the hashcode changes, then you are not using the right kind of object for a key. A key should be immutable. The only reason for a hashcode to change is when the object mutates in some way. Mutable objects are fair game for values, but they are not useful as keys. May 1, 2018 at 17:48
6

Short answer: Dictionary can't detect that some hashcode changed. There is no event that it can subscribe to. Getting hashcode is just a call to Object.GetHashCode(). That method is called once when you insert the object. For obvious performance reasons Dictionary can't call that method for all the objects in a collection every time you perform some operation on Dictionary.

4

Why doesn't the Dictionary class have logic to move an object to the correct bucket when it detects that the object's hashcode has changed?

Because that defeats the object of a dictionary. The whole of a dictionary is to have an immutable set of keys. Since the key is immutable, its hash value won't change. If your hash values are changing, then that means your keys aren't immutable and a dictionary isn't the right type for you. Take a look at the KeyedCollection<TKey, TItem> class, which is an abstract collection class that lets you override some of the dictionary behaviours under the hood to create hash tables with mutable keys for example. It's obviously slower, but may well suit your needs.

4

If the hash code of the key can change, then the keys can change, and keys that were different can become equal. And now you have a dictionary with equal values and a serious problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.