Skip to main content

Ordonare in sens invers - generic

Era nevoie sa implementez un mecanism de ordonare. Deoarece existau mai multe tipuri de ordonare pe acelasi obiect, am ales sa folosesc IComparer.
IComparer este un mecanism de comparare extern. Implementarea functiei care face compararea nu este in interiorul obiectului, asa cum este in cazul IComparable. Se foloseste de obicei cand modul in care se face comparatie nu este naturala.
Cand se implementeaza interfata IComparer, este nevoie sa implementam metoda int Compare(T obj1,T obj2), care returneaza o valorea
  • pozitiva daca obj1 > obj2;
  • negativa daca obj1 <>
  • zero daca obj1 = obj2;
Pana aici nu apare nici o problema. Dar daca avem nevoie sa putem face si o ordonare inversa( reverse), apar probleme. Nu neaparat la modul de implementare, putem foarte usor sa ne folosim de operatorul de negare !, ci la modul in care facem implementarea. Am cautat un mecanism de ordonare in sens invers, care sa fie cat mai generic.
Solutia pe care o propun este urmatoarea:
public class ComparerReverse<T>: IComparer<T>
where T: class
{
//Stocam implementarea deja existenta.
private readonly IComparer<T> _comparer;

public ComparerReverse(IComparer<T> comparer)
{
_comparer = comparer;
}

public int Compare(T obj1,T obj2)
{
//Apelam Compare de la implementarea de baza, cu cei doi parametri inversati.
return _comparer.Compare(obj2,obj1);
}
}
Prin solutia propusa nu mai este nevoie sa folosim operatorul de negare ! si putem sa folosim aceiasi apelare pentru ambele sensuri de ordonare:
...
IComparer<T> comparerUsa=crescator
?new UsaComparare()
:new ComparerReverse(new UsaComparare());
...
Urmatorul pas este sa cream un extension method care sa faca ordonarea in sens invers:
public static class ComparerReverseExtension
{
public static IComparer<T> Reverse<T>(this IComparer<T> comparer)
{
return new ComparerReverse<T>(comparer);
}
}
Folosind acest extension method putem sa inversam modul in care se face comparatia apeland Reverse() direct la IComparer pe care vrem sa il folosim pentru a face ordonarea in sens invers.

Comments