IComparable работает только в одну сторону
Допустим, у вас есть Employeeкласс. В одном представлении вы хотите показать все Employeesотсортированные по имени - в другом по адресу. Как вы собираетесь достичь этого? Не с IComparable, по крайней мере, никаким идиоматическим способом.
IComparable имеет логику в неправильном месте
Интерфейс используется при вызове .Sort(). В представлении, отображающем Customerотсортированный по имени, вообще нет кода, который бы указывал, как он будет сортироваться.
С другой стороны, Customerкласс предполагает, как он будет использоваться - в этом случае он будет использоваться в списке, отсортированном по именам.
IComparable используется неявно
По сравнению с альтернативами очень трудно увидеть, где используется логика сравнения - или вообще. Предполагая вашу стандартную среду разработки и начиная с Customerкласса, мне придется
- Поиск всех ссылок на
Customer - Найдите те ссылки, которые используются в списке
- Проверьте,
.Sort()вызывали ли эти списки их
Что еще хуже, если вы удалите IComparableреализацию, которая все еще используется, вы не получите никаких ошибок или предупреждений. Единственное, что вы получите, - это неправильное поведение во всех местах, которые были слишком неясны для вас.
Эти проблемы объединены, плюс меняющиеся требования
Сама причина, по которой я начал думать об этом, заключается в том, что для меня это пошло не так. Я успешно использую IComparableв своем приложении в течение 2 лет. Теперь требования изменились, и вещь должна быть отсортирована двумя разными способами. Заметили, что неинтересно проходить шаги, описанные в предыдущем разделе.
Вопрос
Эти проблемы заставляют меня думать, IComparableчто я уступаю IComparerили .OrderBy(), до такой степени, что не вижу ни одного действительного варианта использования, который не будет лучше обслуживаться альтернативами.
Всегда ли лучше использовать IComparerили LINQ, или я не вижу здесь преимуществ / вариантов использования?
IComparable, что подтверждает мою точку зрения.
SortedXXXколлекции, они либо требуют, чтобы сохраненные элементы были, IComparableлибо чтобы они были IComparerпредоставлены. Также обратите внимание, что тривиально изменить порядок естественной сортировки с помощью одного компаратора и заставить его работать со всеми IComparableобъектами.
IComparableсчитается механизмом сравнения по умолчанию . IComparerиспользуется, когда вы хотите переопределить механизм сравнения по умолчанию.
ReverseComparer<T>: gist.github.com/jackfarrington/078e7af7bc82482aa634