Разница между двумя перегрузками Enumerable.Except?

Я пытаюсь понять разницу между двумя перегрузками Enumerable.Except метод т.е.

  • Кроме (IEnumerable, IEnumerable)
  • За исключением (IEnumerable, IEnumerable, IEqualityComparer)

Очевидно, что первое отличие состоит в том, что первая перегрузка использует компаратор равенства по умолчанию, в то время как другая использует IEqualityComparer, но я могу достичь того же результата с первым методом, реализуя интерфейс IEquatable (как упомянуто в документации MSDN Except метод), тогда зачем нужна эта вторая перегрузка?

1 ответ

Решение

Две причины:

  1. Вы можете только реализовать IEquatable<T> для ваших собственных типов... в то время как вы можете указать IEqualityComparer<T> для любого типа, можете ли вы изменить его самостоятельно или нет.

  2. Может быть несколько способов сравнения типа на равенство, но реализация IEquatable<T> только позволяет выразить один из них.

Простым примером всего этого были бы строки - рассмотрим:

string[] x = { "A", "B", "C" };
string[] y = { "A", "c" };

var bc = x.Except(y);
var justB = x.Except(y, StringComparer.OrdinalIgnoreCase);

Мы могли бы хотеть оба результата в разных обстоятельствах, что означает, что мы не могли справиться с обоими IEquatable<T>... и мы не можем изменить как string инвентарь IEquatable<T> тем не мение. (Вы не ограничены StringComparer конечно - вы могли бы написать компаратор равенства, который, например, просто использовал длину строки.)

Это также не относится к LINQ - это обычно имеет место для любого API, который имеет дело с равенством, например HashSet<>, Dictionary<,> и т.п.

Другие вопросы по тегам