Sto usando espressioni lambda per ordinare e cercare una matrice in C#. Non voglio implementare l'interfaccia IComparer nella mia classe, perché ho bisogno di ordinare e cercare su più campi membro.Espressioni lambda C# e IComparer
class Widget
{
public int foo;
public void Bar()
{
Widget[] widgets;
Array.Sort(widgets, (a, b) => a.foo.CompareTo(b.foo));
Widget x = new Widget();
x.foo = 5;
int index = Array.BinarySearch(widgets, x,
(a, b) => a.foo.CompareTo(b.foo));
}
}
Mentre il genere funziona bene, la ricerca binaria dà un errore di compilazione Impossibile convertire espressione lambda al tipo 'System.Collections.IComparer <Widget>' perché non è un tipo delegato. Per qualche ragione, Sort ha overload per IComparer e Comparison, ma BinarySearch supporta solo IComparer. Dopo alcune ricerche, ho scoperto il goffo ComparisonComparer<T>
per convertire il confronto a un IComparer:
public class ComparisonComparer<T> : IComparer<T>
{
private readonly Comparison<T> comparison;
public ComparisonComparer(Comparison<T> comparison)
{
this.comparison = comparison;
}
int IComparer<T>.Compare(T x, T y)
{
return comparison(x, y);
}
}
Questo permette la ricerca binaria per lavorare come segue:
int index = Array.BinarySearch(
widgets,
x,
new ComparisonComparer<Widget>((a, b) => a.foo.CompareTo(b.foo)));
Yuck. C'è un modo più pulito?
Il .NET4.5 prossimo ha un metodo 'Comparer <> create' per la costruzione di un' IComparer <>. 'istanza da un delegato' IComparison <> '. –