С# linq sort - быстрый способ создания экземпляра IComparer

При использовании linq и

c.Sort()

Есть ли хороший встроенный способ определения класса Comparison и/или IComparer без фактического создания отдельного класса?

Ответы

Ответ 1

Это одно из использования лямбда-выражений:

c.Sort( (x,y) => x.A.CompareTo(y.A))

EDIT: Исправлен пример возврата int (с помощью CompareTo) вместо bool

Ответ 2

У меня есть класс ProjectionComparer в MiscUtil, поэтому вы можете сделать:

IComparer<Foo> comparer = ProjectionComparer<Foo>.Create(x => x.Name);
c.Sort(comparer);

Код также находится в этом ответе.

Вы можете создать экземпляр Comparison<T> непосредственно с помощью выражения лямбда, но мне обычно не нравится дублирование, которое включает. Сказав, что это часто заканчивается несколько короче...

EDIT: Как уже отмечалось, с .NET 4.5 используйте Comparer<T>.Create, чтобы сделать то же самое.

Ответ 3

Джон ответ велик, но может быть немного устаревшим, с выпуском .NET 4.5 мы теперь (наконец!) имеем этот замечательный метод Comparer<T>.Create

items.Sort((x, y) => x.Value.CompareTo(y.Value)); //sorting List<T>                
items.OrderBy(x => x, Comparer<Item>.Create((x, y) => x.Value.CompareTo(y.Value))); //sorting IEnumerable<T>

Предполагая, что Item определяется примерно так:

class Item
{
    public readonly int Key;
    public readonly string Value;

    public Item(int key, string value)
    {
        Key = key;
        Value = value;
    }
}

Ответ 4

Я понятия не имею, что c.Sort() в вашем примере, поскольку это может быть много вещей (вы имеете в виду List<T>.Sort()?), но одна вещь, в которой он уверен, не является LINQ. LINQ не имеет Sort() - он имеет OrderBy().

Тем не менее, последний также работает с IComparer, и нет способа создать экземпляр анонимного класса, реализующего интерфейс "inline", поэтому вам нужно будет определить класс.

Для List<T>.Sort() существует перегрузка, которая принимает Comparison<T>. Поскольку это тип делегата, вы можете использовать lambda для предоставления функции inline:

List<int> xs = ...;
xs.Sort((x, y) => y - x); // reverse sort

Ответ 5

Если объекты в списке c уже реализуют IComparable, вам не нужен другой. Но если вам нужно индивидуальное сравнение, вы можете реализовать IComparer во вложенном классе. Вы также можете использовать выражение лямбда для создания метода сравнения "на лету":

persons.Sort( (person1, person2) => person1.Age.CompareTo( person2.Age ) );