po prostu musiałem dodać kolejną odpowiedź, ponieważ jeden z bardziej oczywiste (i najłatwiejszym do wdrożenia) rozwiązania nie zostały wymienione - nie licząc zbiorów w twojej GetHashCode
obliczenie!
Najważniejszą rzeczą, o której zapomniałem, jest to, że niepowtarzalność wyniku GetHashCode
nie jest wymagana (lub w wielu przypadkach nawet jest to możliwe). Nierówne obiekty nie muszą zwracać nierównych kodów skrótu, jedynym wymaganiem jest to, że równe obiekty zwracają równe kody skrótu. Więc o tej definicji, co następuje realizacja GetHashCode
jest poprawna dla wszystkich obiektów (zakładając, że jest to poprawne Equals
realizacja):
public override int GetHashCode()
{
return 42;
}
Oczywiście byłoby to wydajność najgorszą możliwą wydajność w hashtable odnośnika, O (n) zamiast O (1), ale nadal jest funkcjonalnie poprawny. Z tego względu moją ogólną rekomendacją podczas implementacji GetHashCode
dla obiektu, który ma kolekcję dowolnego typu jako jednego lub więcej jej członków, jest po prostu zignorowanie ich i obliczenie wartości GetHashCode
wyłącznie na podstawie pozostałych elementów skalarnych. To mogłoby działać całkiem dobrze, z wyjątkiem sytuacji, gdy wstawisz do tabeli mieszania ogromną liczbę obiektów, w których wszystkie ich elementy skalarne mają identyczne wartości, co daje identyczne kody skrótu.
Ignorowanie elementów kolekcji podczas obliczania kodu skrótu może również poprawić wydajność, pomimo zmniejszenia rozkładu wartości kodu skrótu. Pamiętaj, że użycie kodu skrótu ma poprawić wydajność w tabeli mieszania, nie wymagając połączenia z numerem Equals
N, a zamiast tego będzie wymagać tylko raz wywołania GetHashCode i szybkiego sprawdzania tablicy hash. Jeśli każdy obiekt ma wewnętrzną tablicę zawierającą 10 000 elementów, które wszystkie uczestniczą w obliczaniu kodu skrótu, wszelkie korzyści uzyskane przez dobrą dystrybucję zostaną prawdopodobnie utracone. Byłoby lepiej mieć nieznacznie mniej rozproszonego kodu skrótu, jeśli generowanie go jest znacznie mniej kosztowne.
Czy możesz wyjaśnić rozumowanie właściwej wersji GetHashCode()? –
@ Vinko: Czy możesz wyjaśnić? Masz na myśli "dlaczego kod hash ma znaczenie?" - lub "dlaczego to podejście?". Biorąc pod uwagę twoją reputację i liczbę odpowiedzi, zakładam to drugie; jest to po prostu sposób na uzyskanie wartości mieszającej, która uwzględnia wszystkie wartości pod uwagę "pomnóż przez liczbę pierwszą i dodaj następny skrót" to bardzo powszechne podejście do mieszania, które unika kolizji (kontrast xor; w takim przypadku zbiór "wszystkich 8s "może łatwo dać przewidywalny kod skrótu równy 0). Czy coś ominąłem? –
Zobacz też: http: //stackoverflow.com/questions/263400#263416 ... inna liczba pierwsza, ale ten sam efekt. –