Reputation: 1218
is it safe to use an object referece as dictionary key or sould I use some identifier?
Here is the scenario: suppose you have a class "MyClass" with it's own identfier. For the example think of a unique integer value. Now I want to lookup additional information for that class using a dictionary. I could specify the dictionary as Dictionary(of Integer, <sometype>)) or the use the object type itself as key. Then the dictionary would be Dictionary(of <MyClass>, <sometype>).
I am not sure if the second approach is stable enough. I would assume that a key of type <MyClass> will translate to a reference pointing to the object specified as key. If so, then that will be an integer again (I would guess). With respect to performance both approaches should then be the same. But I am concerned that refrences could change due to memory compaction like mentioned here. If that is true, the reference stored in the dictionary would be invalid. So in one case I would find a certain dictionary item and in another case after the memory compaction I would fail to find the same object because its reference changed. (I don't know how to explain this any shorter, but I hope, you get the point.)
I found a similar question here, but that doesn't answer my question. If I missed an existing question, please kindly post a link.
Thanks, Sascha
Upvotes: 0
Views: 116
Reputation: 1502406
If you don't override Equals
and GetHashCode
, then you'll end up with equality based on reference identity. In other words, x.Equals(y)
will be true if and only if Object.ReferenceEquals(x, y)
is true. For hash codes, x.GetHashCode() = y.GetHashCode()
will be true if x.Equals(y)
is true, but it's possible (but unlikely) for the hash codes to be equal even if the two references are not equal. Garbage collection and object relocation does not affect this.
You could also override Equals
and GetHashCode
in your class, to make objects equal based on the data within them - just like String
does. That way you could look up an entry in the dictionary where the key in the dictionary is one object, and the key you're providing to TryGetValue
(or the indexer) is a "different but equal" object. If you do this, you should usually only base equality on aspects of your object which can't change over the object's lifetime - or clearly document that the mutable aspects should not be changed after using the object as a dictionary key.
It's reasonably common to override Equals
and GetHashCode
, and also implement IEquatable(Of T)
- but that doesn't mean it's always the right thing to do. It's usually appropriate for reasonably "primitive" types rather than business-specific types - e.g. for Point
rather than Customer
. But that's only general guidance - you should think of the pros and cons for your specific situation.
Upvotes: 4