Jay said:
Edward,
In addition to Jon's comments.
By value classes, do you mean value types or reference types that
have value semantics?
I don't see where I mentioned value classes in my original post but usually
I mean value types. In C# these are structs and in C++ they are __value
class.
I've noticed that System.Drawing.Point (a value type) always returns
0 for GetHashCode where as Equals is overloaded to perform normal
comparisons.
That sounds normal.
I would override Equals to perform equality checks on mutable types,
considering the recommendation to also override GetHashCode. Seeing
as my mutable type is not a good candidate for a key in a HashTable I
probably would not worry about overriding GetHashCode and ensuring
the immutable nature of Equals & GetHashCode...
http://msdn.microsoft.com/library/d...f/html/frlrfSystemObjectClassEqualsTopic1.asp
States: "Types that override Equals must also override GetHashCode;
otherwise, Hashtable might not work correctly."
Where as:
http://msdn.microsoft.com/library/d...ml/frlrfsystemobjectclassgethashcodetopic.asp
States: "Classes that might be used as a key in a hash table must also
override this method, because objects that are used as keys in a hash
table are required to generate their own hash code through this
method."
Where as the guidelines themselves state:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpgenref/html/cpconEquals.asp
"Override the GetHashCode method to allow a type to work correctly in
a hash table"
&
"Successive invocations of x.Equals(y) return the same value as long
as the objects referenced by x and y are not modified. "
This is the line, from the GetHashCode documentation, that is bothering me:
"Derived classes that override GetHashCode must also override Equals to
guarantee that two objects considered equal have the same hash code;
otherwise, Hashtable might not work correctly."
Now let us consider two __value class objects. I have an immutable field in
each object which I use for the hash code and do not change. I calculate
that initial value from a mutable field in the object and store it away in
an immutable field , and which I subsequently use to return my hash code so
that it always stays the same for my given object. The hashcode value of
object One is 1 and the hash code value of object two is 2. The mutable
value of object One and object Two are also different because I am
calculating, through some algorithm, the immutable field's hash code value
from them. I calculate my Equals method based on the mutable value, and they
start out being different. All is well.
Now object One's mutable value changes to be the same as the mutable value
for object two. Naturally my two objects now return true when passed into my
Equals method. But of course they continue to return different GethashCode
values since the hash code value is based on the original mutable field. But
I am breaking the injunction quoted above by me.
This means to me that mutable objects can not be placed in hash code
containers, and can not implement GetHashCode, and can not implement Equals
because the Equals documentation states:
"Types that override Equals must also override GetHashCode; otherwise,
Hashtable might not work correctly."
The only thing I have missed in my original argument that Equals and
GetHashCode are only for immutable objects is that a mutable object can be
made to follow the documentation if, for any mutable object of any given
type, the same hash code is always returned. In this way, obviously followed
by System.Drawing.Point, whether or not two mutable objects of a particular
type are Equals, they always return the same hash value. Is this then
essentially the rule for all mutable objects ?:
"All mutable objects of a given type must always return the same hash
value."
It seems to follow from my arguments and both our quotes from above. But I
have a feeling that if Hashtable expects two objects that are Equals to
return the same GetHashCode, it also clearly expects two objects that are
not equal to not return the same hash code; and of course this is not the
case with the only situation for mutable objects regarding Equals and
GetHashCode which seems acceptable from the other documentation.
So my confusion about this still exists, and I am still seeking
clarification.