Mało kto wie jednak że C# oferuje aż 4 takie funkcje:
Code:
Przeważnie nie definiujemy wszystkich 4 funkcji a tylko dwie z nich: Equals oraz operator ==
Należy pamiętać, że zmieniając jedną z nich możemy wpłynąć nieświadomie na pozostałe.
Oprócz tych 4 metod istnieje także interfes IEquatable<T>. Implementacja tego interfejsu jest wskazana tam, gdzie definiujemy funkcję Equals (interfejs ten zawiera jedną metodę Equals).
Mnogość metod sprawdzania równości wynika z prostego faktu:
- Jeżeli porównujemy dwa obiekty, to są one równe gdy ich referencje wskazują na ten sam obiekt
- Jeżeli porównujemy dwa typy wartościowe, to są one równe wtedy kiedy ich wartości są równe
Pierwsza z metoda, której nigdy nie zmieniamy - ReferenceEquals() zwraca prawdę, gdy dwie zmienne odnoszą się do tego samego obiektu - do tej samej komórki pamięci. Metoda ta nie sprawdza zawartości obiektu. Wynika z tego iż dla typów wartościowych zawsze zwraca fałsz (false). Nawet jeżeli porównany za pomocą tej metody zmienną wartościową z samą sobą dostaniemy false - związane jest to z boxing-iem.
Druga funkcja, której nigdy nie zmieniamy to statyczna funkcja Equals zdefiniowana w klasie Object:
Code:
Funkcji tej używamy gdy nie znamy typu zmiennych, które porównujemy. Z kodu powyższego możemy odczytać, że rozważane są trzy przypadki:
- sprawdzenie za pomocą metody ReferenceEquals czy obiekty wskazują na tę samą komórkę pamięci
- sprawdzenie czy któryś z argumentów nie jest nullem
- wykorzystanie metody Equals
Kolejną metodą jest wirtualna metoda Equals. Kiedy ją nadpisujemy?
- w przypadku typów wartościowych - zawsze
- w przypadku typów referencyjnych - wtedy kiedy zależy nam na równości zawartości obiektu
Zasady podczas nadpisywania metody Equals:
- metoda ta nie powinna rzucać wyjątku - nie ma to większego sensu
- w pierwszej kolejności sprawdzamy czy wchodzący do metody parametr nie jest nullem
- drugie sprawdzenie dotyczy tego czy porównujemy dwa obiekty tego samego typu
- implementując IEquatable<T> - zapewniamy, że tworzymy silnie typowane sprawdzenie.
- nadpisując metodę Equals należy także nadpisać GetHashCode
Code:
Nadpisanie operatora == jest rzeczą banalną. W przypadku typu wartościowego jego nadpisanie jest bardzo ważne w aspekcie wydajności - jeżeli tego nie zrobimy podczas porównywania będzie stosowana refleksja.
Jeżeli chodzi o typy referencyjne operator== sprawdza równość referencji. Jeżeli jest to tylko możliwe nie powinniśmy zmieniać tej funkcjonalności.
Brak komentarzy:
Prześlij komentarz