SortedSet <T> и анонимный IComparer <T> в конструкторе не работает
Как анонимные функции работают как аргументы методов, но не в аргументах конструктора?
Если я создаю List<string>
, он имеет метод Sort со следующей подписью:
public void Sort(IComparer<T> comparer)
где выполняется следующее:
List<string> list = new List<string>();
list.Sort( (a,b) => a.CompareTo(b) );
SortedSet имеет конструктор с аналогичной сигнатурой:
public SortedSet(IComparer<T> comparer)
но это не удается при использовании анонимной функции в конструкторе. Недопустимо следующее:
SortedSet<string> set = new SortedSet<string>( (a, b) => a.CompareTo(b) );
Создание класса сортировки работает нормально, как ожидалось:
public class MyComparer : IComparer<string>
{
public int Compare(string a, string b)
{ return a.CompareTo(b); }
}
SortedSet<string> set = new SortedSet<string>( new MyComparer() );
Ответы
Ответ 1
Это потому, что конструктор принимает IComparer<T>
(интерфейс), а не Comparison<T>
(делегат). Anon-methods/lambdas могут поддерживать делегаты, но не (напрямую) интерфейсы. Это довольно легко обернуть, хотя - например:
class FuncComparer<T> : IComparer<T>
{
private readonly Comparison<T> comparison;
public FuncComparer(Comparison<T> comparison) {
this.comparison = comparison;
}
public int Compare(T x, T y) {
return comparison(x, y); }
}
Теперь вы можете использовать:
SortedSet<string> set = new SortedSet<string>(
new FuncComparer<string>( (a, b) => a.CompareTo(b) ));
Ответ 2
В выпуске .NET Framework 4.5 представлен метод factory Comparer<T>.Create
:
var set = new SortedSet<string>(
Comparer<string>.Create((a, b) => a.CompareTo(b)));
Ответ 3
В вашем случае List.Sort использует эту подпись
public void Sort(Comparison<T> comparison)
но не этот
public void Sort(IComparer<T> comparer)
Ответ 4
Объяснение замечательно, что SortedSet принимает интерфейс, но не является делегатом. (Но Java делает).
Из-за этого ребята .Net предоставляют метод factory для создания такого объекта, поэтому вам не нужно определять для него новый класс.
var set = new SortedSet<string>(
Comparer<string>.Create((a, b) => a.CompareTo(b))
);