2009-09-04 2 views

ответ

53

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

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

EDIT: Fixed пример для возврата INT (используя CompareTo) вместо BOOL

+1

Я не думаю, что это будет работать для IComparer, поскольку lamda должна возвращать int, а не bool. –

+3

Вы правы. Это работает для IComparison, а не для IComparable. Проведите большую часть часа, пытаясь добиться чего-то подобного, чтобы работать с NUnit CollectionAssert.IsOrdered метод только для того, чтобы понять, что это не так. Вся документация и статьи сбивают с толку, поскольку они используют метод сортировки в качестве примера. У метода сортировки есть перегрузки, которые берут либо IComparer, и IComparison. Это работает только с методом сортировки из-за перегрузки IComparison. – Brett

+3

@Brett Но в следующем .NET4.5 вы можете создать экземпляр 'IComparer <>' из 'IComparison <>' делегата, вызвав новый статический заводский метод 'Comparer <>. Create'. –

16

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

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

Код также находится в this answer.

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

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

+0

Я не получаю последние 2 предложения. Не могли бы вы рассказать немного? Приветствия ... – flq

+0

Хорошо, если вы посмотрите на принятый ответ, у него есть избыточная информация: часть «А» указана дважды. (Он также не будет компилироваться, потому что он возвращает bool вместо int, но неважно). Это нормально, если это одно простое свойство, но становится больнее, если это сложное выражение. –

+0

@JonSkeet есть что-то подобное в новом .NET (полезный метод для создания IComparer ), см. Мой ответ –

7

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

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

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

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

Ваше право, это не linq - слишком поздно днем ​​ – Daniel

+0

«нет способа создать экземпляр анонимного класса, реализующего интерфейс inline "- это зависит от вашего языка. F # может сделать это просто отлично. –

+2

@Joel: язык четко указан в тегах к вопросу. –

3

Если объекты в список C уже реализовать IComparable вам не нужен еще один. Но если вам нужно индивидуальное сравнение, вы можете реализовать IComparer во вложенном классе. Вы также можете использовать лямбда-выражения для создания метода сравнения на лету:

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

10

Ответ Джона является большим, но может быть немного устарели, с выпуском .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; 
    } 
} 
Смежные вопросы