Итак, у меня есть перечислимое число, и я хочу получить от него разные значения.
При использовании System.Linq
, конечно же, есть метод расширения под названием Distinct
. В простом случае его можно использовать без параметров, например:
var distinctValues = myStringList.Distinct();
Хорошо, но если у меня есть перечислимое количество объектов, для которых мне нужно указать равенство, единственная доступная перегрузка:
var distinctValues = myCustomerList.Distinct(someEqualityComparer);
Аргумент компаратора равенства должен быть экземпляром IEqualityComparer<T>
. Я, конечно, могу это сделать, но это несколько многословно и, ну, в общем, неуклюже.
Я ожидал, что перегрузка потребует лямбда-выражения, например Func<T, T, bool>
:
var distinctValues = myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);
Кто-нибудь знает, существует ли такое расширение или какой-либо эквивалентный обходной путь? Или я что-то упускаю?
В качестве альтернативы, есть ли способ указать IEqualityComparer
inline (смущаю меня)?
Обновить
Я нашел ответ Андерса Хейлсберга на сообщение на форуме MSDN по этой теме. Он говорит:
Проблема, с которой вы собираетесь столкнуться, заключается в том, что когда два объекта сравниваются равными, они должны иметь одно и то же возвращаемое значение GetHashCode (иначе хеш-таблица, используемая внутри Distinct, не будет работать правильно). Мы используем IEqualityComparer, потому что он объединяет совместимые реализации Equals и GetHashCode в единый интерфейс.
Полагаю, это имеет смысл.
.Distinct(new KeyEqualityComparer<Customer,string>(c1 => c1.CustomerId))
и объяснить, почему GetHashCode () важен для правильной работы. - person marbel82   schedule 12.10.2016