IComparable ne fonctionne que dans un sens
Disons que vous avez une Employeeclasse. Dans une vue, vous voulez tout afficher Employeestrié 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 Customertrié par nom, aucun code n'implique comment il va être trié.
D'un autre côté, la Customerclasse 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 Customerclasse, 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 IComparableimplé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 IComparablemon 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 IComparablecomme inférieur IComparerou .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 IComparerou LINQ, ou y a-t-il des avantages / cas d'utilisation que je ne vois pas ici?
IComparableplus, ce qui renforce mon argument.
SortedXXXcollections, elles nécessitent soit que les éléments stockés le soient, IComparablesoit qu'ils soient IComparerfournis. Notez également qu'il est trivial d'inverser l'ordre de tri naturel avec un comparateur et de le faire fonctionner avec tous les IComparableobjets.
IComparableest considéré comme le mécanisme de comparaison par défaut . IComparerest utilisé lorsque vous souhaitez remplacer le mécanisme de comparaison par défaut.
ReverseComparer<T>: gist.github.com/jackfarrington/078e7af7bc82482aa634