09 sierpnia 2010
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:
- 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.
- 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.
- 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ć ;)
Dodaj komentarz