I'd like to hear from the community on how I should go about implementing GetHashCode (or override it) for my object. I understand I need to do so if I override the equals method. I have implemented it a fair amount of times, sometimes just calling the base method. I understand that my object should equal another instance of the object if it contains the same details (members). What is the best way to get a hash code from the class's members?
-
2Consider closing as duplicate of stackoverflow.com/a/720282/93922Tetsujin no Oni– Tetsujin no Oni2012-01-25 20:31:24 +00:00Commented Jan 25, 2012 at 20:31
-
3Before you do this, I recommend that you read and understand my article on it: blogs.msdn.com/b/ericlippert/archive/2011/02/28/…Eric Lippert– Eric Lippert2012-01-25 20:36:59 +00:00Commented Jan 25, 2012 at 20:36
-
Thanks, I understand that this may be a common question and I should have done a little more hunting around. Thanks for your helpZivka– Zivka2012-01-25 20:39:37 +00:00Commented Jan 25, 2012 at 20:39
-
4@Fildor: It is here: ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcodeEric Lippert– Eric Lippert2021-01-28 19:51:07 +00:00Commented Jan 28, 2021 at 19:51
-
1@EricLippert Awesome, thanks!Fildor– Fildor2021-01-29 07:50:52 +00:00Commented Jan 29, 2021 at 7:50
|
Show 2 more comments
1 Answer
Let's say your class looks like this:
class Frob {
public string Foo { get; set; }
public int Bar { get; set; }
public double FooBar { get; set; }
}
Let's say you define equals so that two instances of Frob are equal if their Foo and their Bar are equal, but FooBar doesn't matter.
Then you should define GetHashCode in terms of Foo and Bar. One way is like this:
return this.Foo.GetHashCode() * 17 + this.Bar.GetHashCode();
Basically, you just want to incorporate all the fields that go into defining the equality. One way is to just keep accumulating and multiplying by 17 like I've done. It's fast, it's simple, it's correct, and it usually gives a good distribution.
18 Comments
George Duckett
I have a feeling this should be a question itself, but why 23?
geofftnz
maybe point out that GetHashCode only tells you if two objects might be considered equal. There's still the posibility of a hash collision.
svick
Be careful with implementing
GetHashCode() (and Equals()) as depending on mutable data, like here. If you put such object into a hash-based dictionary, and then mutate it, the dictionary won't work correctly anymore. Ideally, GetHashCode() (and Equals()) should depend only on immutable data.mortb
I think the calculation should be wrapped with the
unchecked keyword, like so: unchecked(this.Foo.GetHashCode() * 17 + this.Bar.GetHashCode()). The sum might be larger than int.MaxValue.mortb
@Quintus: I stand corrected. When assigning
Bar = int.MaxValue; Foo = "something", running the GetHashCode() function and not having the unchecked keyword, the code will run and produce a negative hashcode and not crash, so the unchecked keyword is not necessary |