Why do I have to override Equals() and GetHasCode() if I add operator == and != ?

  • Thread starter Thread starter Fernando Cacciola
  • Start date Start date
F

Fernando Cacciola

I can't find the answer to that in the Documentation.
Besides, I don't know under what circumstances will Equals() and
GetHashCode() be called.

TIA

Fernando Cacciola
 
Fernando Cacciola said:
I can't find the answer to that in the Documentation.
Besides, I don't know under what circumstances will Equals() and
GetHashCode() be called.


Hi Fernando,

The default implementation of Equals() does reference equality, which simply
means that two references refer to the same object. Often, you'll want some
type of value equality when comparing two instances of the same type. For
example, if you have a customer object, you may consider them equal if their
CustomerID numbers were equal.

The reason you would want to override GetHashCode is because the default
System.Object implementation is not guaranteed to be unique.

Joe
 
The reason you would want to override GetHashCode is because the default
System.Object implementation is not guaranteed to be unique.

Also, if you override Equals, you MUST override GetHashCode. Otherwise your
objects won't work if you try to use them as hash keys.

The rule here is: "if two objects are equal (in the Equals sense), they must
have the same hash code".

This is because the hash table logic uses GetHashCode to find the bucket and
then uses Equals to compare keys inside a bucket. So, if you only override
Equals, the hash table won't find the same bucket for two keys that are
equal.

Bruno.
 
Joe Mayo said:
The reason you would want to override GetHashCode is because the default
System.Object implementation is not guaranteed to be unique.

No - the reason you want to override GetHashCode is so that two
independent objects which are equal (according to Equals) give the same
hash code, so that you can match an original key with another equal one
in a hash table.
 
Jon Skeet said:
No - the reason you want to override GetHashCode is so that two
independent objects which are equal (according to Equals) give the same
hash code, so that you can match an original key with another equal one
in a hash table.

Apologies to OP on that. I had #6 of Chris Brumme's Blog on my mind and
replied with something that didn't relate to the question:

http://blogs.msdn.com/cbrumme/archive/2003/11/10/51554.aspx

Thanks Jon,

Joe
 
Thanks to all who responded.
One thing worries me though:

If I implement operator ==, the fact that I *must* also implement Equals()
indicates that "someone" will call Equals() to compare instead of operator
==.

This would be fine except that Equals() takes an "object", meanig that
boxing will ocurr if the types to compare are Value Types. Thus, Equals() is
largely inefficient for value types, unlike operator ==.

So, what components will call Equals() and how can I avoid it? (to prevent
boxing).

TIA
 
Fernando said:
Thanks to all who responded.
One thing worries me though:

If I implement operator ==, the fact that I *must* also implement Equals()
indicates that "someone" will call Equals() to compare instead of operator
==.

This would be fine except that Equals() takes an "object", meanig that
boxing will ocurr if the types to compare are Value Types. Thus, Equals() is
largely inefficient for value types, unlike operator ==.

So, what components will call Equals() and how can I avoid it? (to prevent
boxing).

TIA

You have no control over this. Every object, including value types,
provides the Equals() method. It's up to the calling code to decide
whether it wants to take the overhead of boxing/unboxing. For example,
the Hashtable needs to be able to handle keys of any type, so it calls
Equals().
 
Fernando Cacciola said:
Thanks to all who responded.
One thing worries me though:

If I implement operator ==, the fact that I *must* also implement Equals()
indicates that "someone" will call Equals() to compare instead of operator
==.

This would be fine except that Equals() takes an "object", meanig that
boxing will ocurr if the types to compare are Value Types. Thus, Equals() is
largely inefficient for value types, unlike operator ==.

So, what components will call Equals() and how can I avoid it? (to prevent
boxing).

Usually, classes which call Equals() will already have a boxed version
- for instance, ArrayLists, Hashtables etc.
 
Back
Top