SortedSet <T>и анонимный IComparer <T>в конструкторе не работают - PullRequest
17 голосов
/ 28 июня 2010

Почему анонимные функции работают как аргументы в методах, но не в аргументах конструктора?


Если я создаю 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() );

Ответы [ 4 ]

28 голосов
/ 28 июня 2010

Это потому, что конструктор принимает IComparer<T> (интерфейс), а не Comparison<T> (делегат). Anon-method / 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) ));
22 голосов
/ 22 апреля 2014

В выпуске .NET Framework 4.5 представлен фабричный метод Comparer<T>.Create:

var set = new SortedSet<string>(
    Comparer<string>.Create((a, b) => a.CompareTo(b)));
2 голосов
/ 09 августа 2017

Отличное объяснение, что SortedSet принимает интерфейс, но не делегат. (Но Java принимает).

Из-за этого .Net парни предоставляют фабричный метод для создания такого объекта, поэтомуне нужно определять новый класс для этого.

var set = new SortedSet<string>( 
    Comparer<string>.Create((a, b) => a.CompareTo(b))
);
0 голосов
/ 28 июня 2010

В вашем случае List.Sort использует эту подпись

public void Sort(Comparison<T> comparison)

, но не эту

public void Sort(IComparer<T> comparer)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...