IComparable działa tylko w jedną stronę
Powiedzmy, że masz Employeeklasę. W jednym widoku chcesz pokazać wszystkie Employeesposortowane według nazwy - w innym według adresu. Jak zamierzasz to osiągnąć? Nie z IComparable, przynajmniej nie w idiomatyczny sposób.
IComparable ma logikę w niewłaściwym miejscu
Interfejs jest używany przez wywołanie .Sort(). W widoku pokazującym Customerposortowane według nazwy, w ogóle nie ma kodu, który wskazywałby , jak będzie sortowany.
Z drugiej strony Customerklasa zakłada, w jaki sposób będzie używana - w tym przypadku będzie używana na liście posortowanej według nazw.
IComparable jest używany niejawnie
W porównaniu z alternatywami bardzo trudno jest zobaczyć, gdzie stosowana jest logika porównawcza - lub w ogóle. Zakładając standardowe IDE i zaczynając od Customerklasy, będę musiał
- Wyszukaj wszystkie odniesienia do
Customer - Znajdź odniesienia, które są używane na liście
- Sprawdź, czy te listy kiedykolwiek
.Sort()do nich dzwoniły
Co gorsza, jeśli usuniesz IComparableimplementację, która jest nadal używana, nie pojawi się błąd ani ostrzeżenie. Jedyne, co dostaniesz, to złe zachowanie we wszystkich miejscach, które były zbyt niejasne, abyś o tym pomyślał.
Te problemy łącznie, a także zmieniające się wymagania
Powodem, dla którego pomyślałem o tym, jest to, że poszło mi nie tak. Z radością korzystam IComparablez aplikacji od 2 lat. Teraz wymagania się zmieniły i rzecz musi zostać posortowana na 2 różne sposoby. Zauważyłem, że nie jest fajnie przechodzić przez kroki opisane w poprzedniej sekcji.
Pytanie
Te problemy sprawiają, że uważam się IComparableza gorszy IComparerlub .OrderBy()do tego stopnia, że nie widzę żadnego ważnego przypadku użycia, który nie byłby lepiej obsługiwany przez alternatywy.
Czy zawsze lepiej jest używać IComparerlub LINQ, czy też są zalety / przypadki użycia, których tu nie widzę?
IComparablejuż używać , co wzmacnia mój punkt widzenia.
SortedXXXkolekcji, wymagają one, aby przechowywane elementy były IComparablelub miały IComparerzapewnioną. Zauważ też, że odwrócenie naturalnej kolejności sortowania za pomocą jednego urządzenia porównującego i sprawienie, by działała ze wszystkimi IComparableobiektami , jest banalne .
IComparablejest uważany za domyślny mechanizm porównania. IComparerjest używany, gdy chcesz zastąpić domyślny mechanizm porównywania.
ReverseComparer<T>: gist.github.com/jackfarrington/078e7af7bc82482aa634