Список <T>Сортировка использует Comparer <T>вместо IEquatable. Почему? - PullRequest
11 голосов
/ 26 мая 2011

Я написал целую кучу объектов, которые все являются частями коллекций и по которым мне нужно будет выполнить много сортировки и поиска. На большинстве этих объектов я реализовал и переопределил метод Equals, IEquatable и operator! и operator==.

Теперь я перехожу к желанию использовать List<T>.Sort для объекта, реализовавшего все вышеперечисленное, и оказывается, что мне нужно реализовать IComparable для пользовательской сортировки.

Почему Сортировка использует IComparable и какой смысл иметь IEquatable во всех моих объектах?

Кроме того, какое отношение имеет Object.Equal переопределение ко всему этому?

Ответы [ 7 ]

14 голосов
/ 26 мая 2011

Невозможно использовать IEquatable<T> для сортировки - знание того, равны ли две вещи, не поможет вам оценить их. Однако он может использовать IComparable<T>, если ваши типы реализуют его, или любой IComparer<T> (включая Comparer<T>.Default) для предоставления пользовательского объекта сравнения. Функциональный стиль (Comparison<T>) также удобен для специальной сортировки без большого количества кода:

list.Sort((x,y) => string.Compare(x.Name, y.Name));

, но если вам нужна простая порядковая сортировка, попросите T реализовать IComparable<T> и просто использовать:

list.Sort();
7 голосов
/ 26 мая 2011

Равенство может дать только результат того, равны ли два объекта или нет.Он не может сказать вам, должен ли x идти до или после y в отсортированном порядке.Учитывая только равенство, как бы вы предложили, чтобы List<T> выполнял какую-либо сортировку?

Точка реализации IEquatable<T> - это когда равенство , что важно, например, в HashSet<T>или в качестве ключа введите Dictionary<TKey, TValue>.Аналогично, они не могут быть эффективно реализованы с использованием только IComparable<T>, поскольку он не предоставит хэш-код.

Два интерфейса в основном используются в разных ситуациях.

4 голосов
/ 26 мая 2011

Потому что сортировка опирается не только на равенство, но и на относительный ранг.Для того, чтобы сортировать, вам нужно знать положение объектов относительно друг друга.Больше, чем меньше, равно.

4 голосов
/ 26 мая 2011

Поскольку IComparable позволяет определить, является ли объект "меньшим" или "больше", чем другой объект, тогда как IEquatable помогает выяснить, являются ли два объекта "равными".

Первое необходимо для сортировки, потому что просто знание того, какие объекты имеют одинаковую ценность, не поможет вам расположить их в определенном порядке.

0 голосов
/ 26 мая 2011

Равенство говорит вам, если два экземпляра равны.Сопоставимость говорит вам, как их сортировать.

Вы переопределяете версию экземпляра Object.Equals, когда лучше, чем среда выполнения, знаете, как работает равенство для вашего типа.

Равенство для ссылочных типов по умолчанию установлено наСправочное равенство (одна и та же ссылка - один и тот же объект).

object o1 = new object();
object o2 = o1;

if(o2==o1)
{
    Console.WriteLine("These reference types are equal");
}

object o3 = new object();

if(o2 != o3)
{
    Console.WriteLine("These reference types are not equal");
}

Равенство по умолчанию для типов значений означает, что все переменные-члены равны.Как правило, вы должны переопределять Equals для типов значений, потому что вы, вероятно, будете лучше знать, что означает equals.

Каким образом эта сопоставимость эффектов влияет на то, что сопоставимость в некоторой степени зависит от равенства.Чтобы знать, что значит быть меньше или больше, чем нужно, нужно знать, что значит «.»

0 голосов
/ 26 мая 2011

Используя интерфейс IEquatable, вы определяете отношение эквивалентности , но для сортировки вам необходим порядок .

0 голосов
/ 26 мая 2011

Ну, как вы можете видеть в других вопросах по этой теме , IEquatable<T> проверяет равенство, а IComparable<T> вводит ранг, необходимый для сортировки.

...