2009-10-02 18 views
7

Widzę punkt w jawnym wdrażaniu równań i GetHashCode dla moich obiektów.Konsekwentna implementacja operatora równości C#

Ale zastanawiam się, czy to ma jakiś sens również wyraźnie wdrożenia == = operatorzy i tak:!

public static bool operator ==(Salutation left, Salutation right) 
{ 
    return Equals(left, right); 
} 

Czy C# nie automatycznie użyć metody jest równy == gdy wywoływana jest?

Odpowiedz

8

Rzeczywiście ma sens zastąpić operatora równości wraz z Equals. Jest to w rzeczywistości bardzo wskazane.

Firma Microsoft opublikowała oficjalny numer Guidelines for Implementing Equals and the Equality Operator (==) na stronie MSDN. Zdecydowanie polecę tam zalecaną praktykę. Dwa główne punkty to:

  • Wdrożenie metody GetHashCode ilekroć wdrożyć Równa metody. Dzięki temu synchronizowane są kody Equals i GetHashCode.
  • Zastąp metodę Equals za każdym razem, gdy zaimplementujesz operatora równości (==), i spraw, aby zrobili to samo. Pozwala to na kod infrastruktury, taki jak , jako Hashtable i ArrayList, które używają metody do równego traktowania, aby zachowywać się w taki sam sposób jak kod użytkownika napisany przy użyciu operatora równości .

Jon Skeet napisał również useful MSDN blog post na ten temat, podsumowując jak Equals i pracę == operatora domyślnie typów odniesienia/wartość.

Najważniejsze części podane są poniżej:

równości metoda jest tylko jeden wirtualny zdefiniowane w System.Object, a przesłonięte przez którykolwiek zajęcia wybrać zrobić. Operator == jest operatorem , który może być przeciążony przez klasy , ale który zwykle ma zachowanie tożsamościowe .

Dla typów referencyjnych gdzie == nie został przeciążony, porównuje czy dwie referencje odnoszą się do tego samego obiektu - co jest właśnie realizacja równych robi w System.Object.

Typy wartości nie zapewniają przeciążenia domyślnie dla ==. Jednak większość z wartości zapewnia ich własne przeciążenie. Domyślna implementacja równych dla typu wartości jest dostarczana przez ValueType i wykorzystuje odbicia aby porównania, które sprawia, że ​​ znacznie wolniej niż implementacji specyficznych dla danego typu normalnie będzie. Ta implementacja również nazywa się Równa się na parach odniesień w obrębie porównywanych wartości.

+0

Dzięki. Przyjąłem twoją odpowiedź, ale czy możesz edytować niektóre rzeczy, które Joel powiedział? Jak == zachowuje się, jeśli nie zostanie zmienione. – Tigraine

+0

@Tigraine: Nie ma problemu. Właściwie to, co mówi Joel (i o wiele więcej), jest wspomniane na stronie, do której się przyłączyłem, napisanej przez Jona Skeeta. Zacytuję to, jeśli chcesz. – Noldorin

+0

Dzięki .. :) Po prostu jest to łatwiejsze do odczytania;) – Tigraine

2

Jeśli go nie przeładujesz, == sprawdza tylko równanie odniesienia: czy obie strony odnoszą się do tego samego obiektu?

Jeśli potrzebujesz wartości równości (czy różne obiekty po obu stronach mają tę samą wartość?), Możesz przeciążyć operatora. W tym momencie prawie zawsze chcesz przeciążyć .Equals() i .GetHashCode() oraz po prostu mieć połączenie == overload .Equals().