L'interfaccia IComparable è obsoleta / "dannosa"?

11

IComparable funziona solo in un modo

Supponiamo che tu abbia una classe Employee . In una vista, vuoi mostrare tutto Employees ordinato per nome - in un altro, per indirizzo. Come hai intenzione di raggiungere questo? Non con IComparable , almeno non in modo idiomatico.

IComparable ha la logica nel posto sbagliato

L'interfaccia viene utilizzata chiamando .Sort() . In una vista che mostra Customer ordinata per nome, non vi è alcun codice per implicare il modo in cui verrà ordinato.
D'altra parte, la classe Customer sta assumendo come verrà utilizzata - in questo caso, verrà utilizzata in una lista ordinata per nome.

IComparable è usato implicitamente

In confronto con le alternative, è molto difficile vedere dove viene utilizzata la logica comparativa, o se non del tutto. Assumendo il tuo IDE standard e partendo dalla classe Customer , dovrò

  1. Cerca tutti i riferimenti a Customer
  2. Trova i riferimenti utilizzati in un elenco
  3. Verifica se tali elenchi hanno mai ricevuto .Sort() su di essi

Ciò che è probabilmente peggio, se rimuovi un'implementazione IComparable ancora in uso, non ricevi alcun errore o avviso. L'unica cosa che otterrai è un comportamento sbagliato in tutti i posti che erano troppo oscuri per te da pensare.

Questi problemi combinati, oltre a cambiare i requisiti

La vera ragione per cui sono venuto a pensare a questo è perché è andato storto per me. Ho usato felice IComparable nella mia domanda per 2 anni. Ora, i requisiti sono cambiati e la cosa deve essere ordinata in 2 modi diversi. Ha notato che non è divertente seguire i passaggi descritti nella sezione precedente.

La domanda

Questi problemi mi fanno pensare a IComparable come inferiore a IComparer o .OrderBy() , al punto di non vedere alcun caso d'uso valido che non sarebbe servito meglio dalle alternative.
È sempre meglio usare IComparer o LINQ, o ci sono vantaggi / casi d'uso che non vedo qui?

    
posta R. Schmitz 08.03.2018 - 18:09
fonte

2 risposte

14

IComparable ha le restrizioni che hai citato, è corretto. È un'interfaccia che era già disponibile in .NET Framework 1.0, dove quelle alternative funzionali e Linq non erano disponibili. Quindi sì, si potrebbe vederlo come un elemento del framework obsoleto che viene principalmente mantenuto per compatibilità all'indietro.

Tuttavia, per molte strutture di dati semplici, un modo di ordinare è probabilmente abbastanza o naturale. In questi casi, disporre di un luogo canonico per implementare la relazione dell'ordine è comunque un buon modo per mantenere il codice DRY, invece di ripetere sempre la stessa logica in ogni chiamata a OrderBy in tutto il luogo.

Sei stato "felicemente usando IComparable nella tua applicazione per 2 anni", come hai scritto, quindi mi sembra che ti sia servito per molto tempo. Quando ora devi convalidare, modificare e testare tutte le chiamate su Sort , potrebbe anche essere un segno che stavi facendo lo stesso tipo di logica di ordinamento in molti punti, che non è colpa di IComparable . Quindi questa potrebbe essere un'occasione per centralizzare più di questa logica in un unico posto, rendendo il tuo codice più ASCIUTTO.

    
risposta data 08.03.2018 - 18:31
fonte
1

Sono d'accordo con i tuoi sentimenti su IComparable

Guarda le osservazioni su Array.Sort()

  • Ogni elemento dell'array deve implementare l'interfaccia IComparable per essere in grado di confrontarsi con ogni altro elemento dell'array. (o viene lanciata un'eccezione)
  • Se l'ordinamento non viene completato correttamente, i risultati non sono definiti.

Probabilmente non avremo mai più la motivazione, comunque! considera object.Equals() un metodo su ogni oggetto che ti consente di confrontare gli oggetti tra loro per vedere se sono "uguali"

Ce l'hai già, ma hai ricevuto il compito di aggiungere Array.Sort() che potresti voler aggiungere object.Compare(object)

    
risposta data 08.03.2018 - 19:37
fonte

Leggi altre domande sui tag