C# — Как реализовать несколько компараторов для класса IComparable‹T›?

У меня есть класс, реализующий IComparable.

public class MyClass : IComparable<MyClass>
{
    public int CompareTo(MyClass c)
    {
        return this.whatever.CompareTo(c.whatever);
    }

    etc..
}

Затем я могу вызвать метод сортировки общего списка моего класса

List<MyClass> c = new List<MyClass>();
//Add stuff, etc.

c.Sort();

и отсортировать список в соответствии с моим компаратором.

Как указать дополнительные компараторы для сортировки моей коллекции по-разному в соответствии с другими свойствами MyClass, чтобы пользователи могли сортировать мою коллекцию по-разному?


person Gary Willoughby    schedule 19.03.2010    source источник


Ответы (4)


Чтобы настроить сортировку в вашем классе:

public static Comparison<MyClass> OtherComparison = delegate(MyClass object1, MyClass object2)
{
    return object1.Whatever.CompareTo(object2.Whatever);
};

Затем для сортировки с использованием вашего нового сравнения:

List<MyClass> myClassList = new List<MyClass>();
myClassList.Sort(MyClass.OtherComparison);

За исключением того, что вы явно не захотите сортировать пустой список :)

person Kevin Crowell    schedule 19.03.2010
comment
+1, хотя вы могли бы написать это более кратко с помощью лямбда-выражения :) - person Mark Seemann; 19.03.2010
comment
Кевин, я боролся с этим уже 2 дня и не могу понять, что он делает. Ваш способ работает, но как написать этот статический метод, не записав его как delegate? - person jp2code; 22.03.2013
comment
@ jp2code Этот ответ заставил меня глубже задуматься о сравнениях. Я задал вопрос об этом, и мне очень нравится принятый ответ. Посмотрите, поможет ли это вам: stackoverflow.com/questions/2488298/ - person Kevin Crowell; 23.03.2013

Вы можете вызвать Sort с конкретным компаратором в качестве аргумента. Ссылка: MSDN

person CookieOfFortune    schedule 19.03.2010
comment
Я проголосовал за этот ответ как за Кевина, потому что я думаю, что они оба являются хорошими решениями. Я использовал это решение, потому что я думаю, что оно проще. itemDescription/ItemNumber: я предоставил ответ, демонстрирующий мою реализацию - person Mark Ainsworth; 06.09.2015

Одним из шагов в этом направлении было бы использование перегрузки Sort, которая позволяет указать IComparer<T> (но не IComparable<T>).

Если у вас уже есть много реализаций IComparable<T>, написать универсальную реализацию IComparer<T>, которая сравнивает два экземпляра IComparable<T>, должно быть тривиально. На самом деле, я немного удивлен, что такого класса еще нет в BCL, но я не смог его найти.

Comparer<T>.Default подходит близко, но не совсем.

person Mark Seemann    schedule 19.03.2010

Если у вас есть несколько способов сортировки списка ваших объектов, вы, очевидно, должны указать, какой вариант выбрать. Вот для чего хороши другие переопределения Sort. Взгляните на IComparer и Сравнение.

person Achim    schedule 19.03.2010