GetHashCode

Metoda w obiekcie GetHashCode() służy do generowania prostego (Int32) skrótu danego obiektu. We własnych klasach powinniśmy ją nadpisać, szczególnie jeśli dane obiekty będą wykorzystywane w kolekcjach typu Dictionary i HashSet.
Jednak powinniśmy zrobić to prawidłowo, przestrzegając 3 prostych zasad:

  1. Jeśli dwa obiekty są sobie równe muszą zwracać ten sam skrót, ale jeśli są różne powinny (ale nie muszą) zwracać różne skróty.
  2. Każdy obiekt powinien zwracać ten sam skrót, dopóki nie został zmodyfikowany jego stan, w ten sposób, że metoda Equals zwracałaby inną wartość, w stosunku do obiektu, z którym był wcześniej równy.
  3. Zwracany skrót powinien być jak najbardziej losowy, opierając się na istotnych polach tego obiektu.

Dzisiejszy post powstał dlatego, że źle napisałem metodę GetHashCode() i dziwnym sposobem Dictionary nie mógł odnaleźć klucza, który przecież był w słowniku! ;]
Dokładniej, metodę GetHashCode oparłem m.in. o pole, które jest bardzo często zmieniane. Było to pole z datą rozpoczęcia zadania na wykresie Gantta. Jeśli przesunąłem zadanie, obiekt generował już inny skrót. Więc nie mogłem obiektu znaleźć w słowniku, który sobie cache'uje skróty, żeby za każdym razem ich od nowa nie liczyć.

Podsumowując: GetHashCode() powinien być oparty o stałe pola, takie jak identyfikator, nazwa która nie może być zmieniona lub inne pola, których zmiana jest jednoznaczna z tym, że jest to już inny obiekt względem metody Equals, którą też powinniśmy odpowiednio nadpisać ;)