Список <T> Сортировка использует Comparer <T> вместо IEquatable, почему?

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

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

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

И что же делает переопределение Object.Equal со всем этим?

Ответ 1

Невозможно использовать 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();

Ответ 2

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 7

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

Вы переопределяете версию экземпляра 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.

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