IComparable funziona solo in un modo
Diciamo che hai una Employeelezione. In una vista, vuoi mostrare tutto Employeesordinato per nome - in un'altra, per indirizzo. Come lo farai? Non con IComparable, almeno non in alcun modo idiomatico.
IComparable ha la logica nel posto sbagliato
L'interfaccia viene utilizzata chiamando .Sort(). In una vista mostrata Customerordinata per nome, non esiste alcun codice che implichi il modo in cui verrà ordinata.
D'altra parte, la Customerclasse presuppone come verrà utilizzata, in questo caso verrà utilizzata in un elenco ordinato per nome.
IComparable è usato implicitamente
In confronto con le alternative, è molto difficile vedere dove viene utilizzata la logica di confronto - o se non del tutto. Supponendo il tuo IDE standard e partendo dalla Customerclasse, dovrò
- Cerca tutti i riferimenti a
Customer - Trova i riferimenti utilizzati in un elenco
- Controlla se quegli elenchi
.Sort()li hanno mai chiamati
Quel che è probabilmente peggio, se si rimuove IComparableun'implementazione ancora in uso, non si ottiene alcun errore o avviso. L'unica cosa che otterrai è un comportamento sbagliato in tutti i luoghi che erano troppo oscuri per farti pensare.
Questi problemi combinati, oltre a cambiare i requisiti
La vera ragione per cui sono venuto a pensarci è perché è andato storto per me. Uso felicemente la IComparablemia candidatura da 2 anni. Ora, i requisiti sono cambiati e la cosa deve essere ordinata in 2 modi diversi. Ha notato che non è divertente passare attraverso i passaggi descritti nella sezione precedente.
La domanda
Questi problemi mi fanno pensare IComparableche sia inferiore IComparero .OrderBy(), al punto da non vedere alcun caso d'uso valido che non sarebbe servito meglio dalle alternative.
È sempre meglio usare IComparero LINQ o ci sono vantaggi / casi d'uso che non vedo qui?
IComparablepiù, il che sta rafforzando il mio punto.
SortedXXXraccolte, richiedono che gli elementi archiviati siano IComparableo siano IComparerforniti. Si noti inoltre che è banale invertire l'ordine di ordinamento naturale con un comparatore e farlo funzionare con tutti gli IComparableoggetti.
IComparableè considerato il meccanismo di confronto predefinito . IComparerviene utilizzato quando si desidera sovrascrivere il meccanismo di confronto predefinito.
ReverseComparer<T>: gist.github.com/jackfarrington/078e7af7bc82482aa634