views:

161

answers:

5

I have a mutable class that I'm using as a key to a generic dictionary. Two keys should be equal only if their references are equal. From what I've read, in this case, I don't need to override Equals, GetHashCode , or implement IEqualityComparer.

Is this correct?

+11  A: 

Yes. The default comparison operation in System.Object uses reference equality. If this behavior is what you want, the defaults should work fine.

Reed Copsey
Though I do worry about the behaviour if someone were to later add these overrides. The bucket in the hashtable would be calculated by the hash of the object at the time it was added. Calls to Contains() and Remove() et al would subsequently fail if the state (and therefore hash) changes.
Paul Ruane
Yes. It's always a tricky one. Hashing of elements requires some prior knowledge of the objects in question. Even if you provided your own overrides, a subclass could override yours...
Reed Copsey
@Reed: Unless you override them yourself, seal them, and make your implementation call the base one.
Jon Skeet
@Jon: True. Sealing the methods and forcing your class + all subclasses to reference equality and hashing works. You're putting a big restriction on your subclasses, in this case, though.
Reed Copsey
A: 

Yes you are correct doing a == comparison (or .Equals) on two objects compares their references if no other overload is specified.

String s = "a";

object test1 = (object)s;
object test2 = (object)s;

Debug.Assert(test1.Equals(test2));
Chris
You can't *override* ==, you can only *overload* it. Moreover, == isn't used in a generic dictionary: Equals and GetHashCode are.
Jon Skeet
+1  A: 

Yes, this is correct. As long as you don't override, reference is the default comparison.

Nick Craver
A: 

As everyone else pointed out already, yes, you are correct. In fact, you definitely do not want to override the equality members if your type is mutable (it has setters). But, if you want to have equality checking which uses values in your type, you can make your type immutable (like String) by ensuring that there are no setters (only the constructor sets values). Or use a struct.

Pat
+1  A: 

I'll add on to what everyone else has said here (yes) but with one more point that no one seems to have mentioned here.

When using generic collections (Dictionary, List, etc) you can override IEquatable to provide a type specific version that can do your comparison without boxing or up/down casting. These generic collections will use this overload when present to do comparisons and it can be a bit more efficient.

As noted in the docs, when implementing IEquatable you still need to override Equals/Hashcode from Object.

Peter Oehlert
I'm glad you mentioned this because I had the same thoughts after looking in reflector. What confused me though was the need to override GetHashcode even though I wouldn't be changing the equivalence test. What would I override GetHashcode with?
Jules