Quick question about a reference type key in a generic dictionary in .Net
Asked Answered
P

6

7

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?

Prehension answered 16/3, 2010 at 15:32 Comment(0)
C
16

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

Condyloid answered 16/3, 2010 at 15:34 Comment(4)
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.World
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...Condyloid
Unless you override them yourself, seal them, and make your implementation call the base one.Aristophanes
@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.Condyloid
A
1

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

Ardolino answered 16/3, 2010 at 15:35 Comment(0)
S
1

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.

Soria answered 16/3, 2010 at 15:50 Comment(1)
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?Prehension
I
0

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.

Indogermanic answered 16/3, 2010 at 15:39 Comment(0)
H
0

For anybody using .Net 5 or later it comes with a ReferenceEqualityComparer class that you can pass to the dictionary's constructor. This means you don't need to worry about someone overriding GetHashCode and Equals in the future.

Hedy answered 24/11, 2021 at 10:58 Comment(0)
D
-1

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));
Digitalism answered 16/3, 2010 at 15:35 Comment(1)
You can't override ==, you can only overload it. Moreover, == isn't used in a generic dictionary: Equals and GetHashCode are.Aristophanes

© 2022 - 2024 — McMap. All rights reserved.