Возможный дубликат:
Когда использовать IComparable <T> Против IComparer <T>
В чем разница между IComparable
и IComparer
интерфейсами? Нужно ли использовать этот интерфейс всегда с помощью метода Array.Sort()
Возможный дубликат:
Когда использовать IComparable <T> Против IComparer <T>
В чем разница между IComparable
и IComparer
интерфейсами? Нужно ли использовать этот интерфейс всегда с помощью метода Array.Sort()
Как следует из названия, 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>
, которые используются для проверки равенства, а не для сравнения/сортировки; хорошая нить здесь, где я написал тот же самый ответ:)
Лучшее объяснение, которое я прочитал, - "Объект, который будет отсортирован, будет реализовывать IComparable, а класс, который будет сортировать объекты, будет реализовывать IComparer". (источник)
Если объекты, которые вы пытаетесь сортировать, не реализуют IComparable, вам нужно создать класс, который реализует IComparer (и принимает эти типы объектов для сравнения) и передает его методу Array.Sort().
IComparable используется для предоставления порядка сортировки по умолчанию для ваших объектов.
IComparer должен предоставить дополнительные механизмы сравнения.
см. эту статью для справки. http://support.microsoft.com/kb/320727
IComparer сравнивает два объекта, которые он дал. IComparable реализуется объектом, который сравнивается, для сравнения с другим.
Это хорошая идея для реализации IComparable для сортировки объектов. IComparable может быть полезна для сортировки по различным критериям (например, сортировка по выбору в объекте).
Также смотрите: Когда использовать IComparable <T> Против IComparer < Т >
Объекты, являющиеся экземплярами классов, которые реализуют IComparable
, можно сравнить с другими объектами. (Прочитайте IComparable
как "Я могу сравнить".) Метод на этом интерфейсе, который делает это, CompareTo
. Это полезно, если вы хотите, чтобы экземпляры таких классов знали, как сравнивать себя с другими объектами.
Объекты, являющиеся экземплярами классов, которые реализуют IComparer
, могут использоваться для сравнения пар объектов. (Прочитайте IComparer
как "Я могу сравнить".) Метод на этом интерфейсе, который делает это, Compare
. Это полезно, если вы хотите отделить логику сравнения от класса сравниваемых объектов. Один случай, когда вы можете использовать это, если у вас есть различные способы сравнения объектов (это нечувствительность к регистру и сравнение строк с учетом регистра).