IComparable
ne fonctionne que dans un sens
Disons que vous avez une Employee
classe. Dans une vue, vous voulez tout afficher Employees
trié par nom - dans une autre, par adresse. Comment allez-vous y parvenir? Pas avec IComparable
, du moins pas de façon idiomatique.
IComparable
a la logique au mauvais endroit
L'interface est utilisée en appelant .Sort()
. Dans une vue montrant Customer
trié par nom, aucun code n'implique comment il va être trié.
D'un autre côté, la Customer
classe suppose comment il va être utilisé - dans ce cas, il sera utilisé dans une liste triée par noms.
IComparable
est utilisé implicitement
En comparaison avec les alternatives, il est très difficile de voir où la logique de comparaison est utilisée - ou pas du tout. En supposant votre IDE standard et à partir de la Customer
classe, je devrai
- Rechercher toutes les références à
Customer
- Trouvez les références utilisées dans une liste
- Vérifiez si ces listes ont déjà fait
.Sort()
appel à elles
Ce qui est probablement pire, si vous supprimez une IComparable
implémentation qui est toujours utilisée, vous n'obtenez aucune erreur ou avertissement. La seule chose que vous obtiendrez est un mauvais comportement dans tous les endroits qui étaient trop obscurs pour que vous y pensiez.
Ces problèmes combinés, ainsi que l'évolution des exigences
La raison même pour laquelle j'ai pensé à cela, c'est parce que ça a mal tourné pour moi. J'utilise heureusement IComparable
mon application depuis 2 ans maintenant. Maintenant, les exigences ont changé et la chose doit être triée de 2 manières différentes. Il a remarqué qu'il n'est pas amusant de suivre les étapes décrites dans la section précédente.
La question
Ces problèmes me font penser IComparable
comme inférieur IComparer
ou .OrderBy()
, au point de ne voir aucun cas d'utilisation valide qui ne serait pas mieux servi par les alternatives.
Est-il toujours préférable d'utiliser IComparer
ou LINQ, ou y a-t-il des avantages / cas d'utilisation que je ne vois pas ici?
IComparable
plus, ce qui renforce mon argument.
SortedXXX
collections, elles nécessitent soit que les éléments stockés le soient, IComparable
soit qu'ils soient IComparer
fournis. Notez également qu'il est trivial d'inverser l'ordre de tri naturel avec un comparateur et de le faire fonctionner avec tous les IComparable
objets.
IComparable
est considéré comme le mécanisme de comparaison par défaut . IComparer
est utilisé lorsque vous souhaitez remplacer le mécanisme de comparaison par défaut.
ReverseComparer<T>
: gist.github.com/jackfarrington/078e7af7bc82482aa634