Ответ 1

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

Что касается , то для чего они предназначены для. Из определения должно быть ясно, что поэтому IComparable<T> (определенный в самом классе T) должен быть стандартом де-факто для обеспечения логики сортировки. По умолчанию используется Sort on List<T> и т.д. Реализация IComparer<T> на T не помогает регулярной сортировке. Впоследствии для реализации IComparable<T> для любого другого класса, отличного от T, мало значения. Это:

class MyClass : IComparable<T>

редко имеет смысл.

С другой стороны,

class T : IComparable<T>
{
    public int CompareTo(T other)
    {
        //....
    }
}

как это сделать.

IComparer<T> может быть полезна, когда вам требуется сортировка на основе пользовательского порядка, но не как общее правило. Например, в классе Person в какой-то момент вам может потребоваться Сортировка людей в зависимости от их возраста. В этом случае вы можете:

class Person
{
    public int Age;
}

class AgeComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Age - y.Age;
    }
}

Теперь AgeComparer помогает сортировать список на основе Age.

var people = new Person[] { new Person { age = 23 }, new Person(){ age = 22 } };
people.Sort(p, new AgeComparer()); //person with age 22 comes first now.

Аналогично IComparer<T> на T не имеет смысла.

class Person : IComparer<Person>

Правда это работает, но не выглядит хорошо для глаз и побеждает логику.

Обычно вам нужно IComparable<T>. В идеале вы можете иметь только один IComparable<T>, тогда как несколько IComparer<T> возможны на основе разных критериев.

IComparer<T> и IComparable<T> в точности аналогичны IEqualityComparer<T> и IEquatable<T>, которые используются для проверки равенства, а не для сравнения/сортировки; хорошая нить здесь, где я написал тот же самый ответ:)

Ответ 2

  • IComparable - определяет интерфейс для объекта с помощью метода CompareTo(), который принимает другой объект того же типа и сравнивает текущий объект с переданным. Он усваивает сравнение с объектом, позволяя выполнять более строгие операции сравнения, и полезно, когда для сравнения объектов типа существует только один логический путь или, по общему мнению, общий способ по умолчанию.
  • IComparer - определяет интерфейс с помощью метода Compare(), который принимает два объекта другого типа (которые не должны реализовывать IComparable) и сравнивает их. Это экстернализирует сравнение и полезно, когда существует много возможных способов сравнения двух объектов типа или когда тип не реализует IComparable (или реализация IComparable отличается по сравнению с тем, что вы хотите), и вы не имеют контроль над источником этого типа.

Ответ 3

Лучшее объяснение, которое я прочитал, - "Объект, который будет отсортирован, будет реализовывать IComparable, а класс, который будет сортировать объекты, будет реализовывать IComparer". (источник)

Если объекты, которые вы пытаетесь сортировать, не реализуют IComparable, вам нужно создать класс, который реализует IComparer (и принимает эти типы объектов для сравнения) и передает его методу Array.Sort().

Ответ 4

IComparable используется для предоставления порядка сортировки по умолчанию для ваших объектов.

IComparer должен предоставить дополнительные механизмы сравнения.

см. эту статью для справки. http://support.microsoft.com/kb/320727

Ответ 5

IComparer сравнивает два объекта, которые он дал. IComparable реализуется объектом, который сравнивается, для сравнения с другим.

Это хорошая идея для реализации IComparable для сортировки объектов. IComparable может быть полезна для сортировки по различным критериям (например, сортировка по выбору в объекте).

Также смотрите: Когда использовать IComparable <T> Против IComparer < Т >

Ответ 6

Объекты, являющиеся экземплярами классов, которые реализуют IComparable, можно сравнить с другими объектами. (Прочитайте IComparable как "Я могу сравнить".) Метод на этом интерфейсе, который делает это, CompareTo. Это полезно, если вы хотите, чтобы экземпляры таких классов знали, как сравнивать себя с другими объектами.

Объекты, являющиеся экземплярами классов, которые реализуют IComparer, могут использоваться для сравнения пар объектов. (Прочитайте IComparer как "Я могу сравнить".) Метод на этом интерфейсе, который делает это, Compare. Это полезно, если вы хотите отделить логику сравнения от класса сравниваемых объектов. Один случай, когда вы можете использовать это, если у вас есть различные способы сравнения объектов (это нечувствительность к регистру и сравнение строк с учетом регистра).