При использовании linq и
c.Sort()
Есть ли хороший встроенный способ определения класса Comparison
и/или IComparer
без фактического создания отдельного класса?
При использовании linq и
c.Sort()
Есть ли хороший встроенный способ определения класса Comparison
и/или IComparer
без фактического создания отдельного класса?
Это одно из использования лямбда-выражений:
c.Sort( (x,y) => x.A.CompareTo(y.A))
EDIT: Исправлен пример возврата int (с помощью CompareTo) вместо bool
У меня есть класс ProjectionComparer
в MiscUtil, поэтому вы можете сделать:
IComparer<Foo> comparer = ProjectionComparer<Foo>.Create(x => x.Name);
c.Sort(comparer);
Код также находится в этом ответе.
Вы можете создать экземпляр Comparison<T>
непосредственно с помощью выражения лямбда, но мне обычно не нравится дублирование, которое включает. Сказав, что это часто заканчивается несколько короче...
EDIT: Как уже отмечалось, с .NET 4.5 используйте Comparer<T>.Create
, чтобы сделать то же самое.
Джон ответ велик, но может быть немного устаревшим,
с выпуском .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;
}
}
Я понятия не имею, что 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
Если объекты в списке c уже реализуют IComparable, вам не нужен другой. Но если вам нужно индивидуальное сравнение, вы можете реализовать IComparer во вложенном классе. Вы также можете использовать выражение лямбда для создания метода сравнения "на лету":
persons.Sort( (person1, person2) => person1.Age.CompareTo( person2.Age ) );