Tak, więc mam wyliczenie i chcę uzyskać od niego odrębne wartości.
Używając System.Linq
, istnieje oczywiście metoda rozszerzenia o nazwie Distinct
. W prostym przypadku można go używać bez parametrów, takich jak:
var distinctValues = myStringList.Distinct();
Dobrze i dobrze, ale jeśli mam wyliczenie obiektów, dla których muszę określić równość, jedynym dostępnym przeciążeniem jest:
var distinctValues = myCustomerList.Distinct(someEqualityComparer);
Argument porównania równości musi być instancją klasy IEqualityComparer<T>
. Mogę to oczywiście zrobić, ale jest to trochę gadatliwe i, no cóż, niezgrabne.
Spodziewałbym się przeciążenia, które zajęłoby lambda, powiedzmy Func <T, T, bool>:
var distinctValues
= myCustomerList.Distinct((c1, c2) => c1.CustomerId == c2.CustomerId);
Czy ktoś wie, czy istnieje jakieś takie rozszerzenie lub jakieś równoważne obejście? A może coś mi brakuje?
Alternatywnie, czy istnieje sposób na określenie inline IEqualityComparer (zawstydza mnie)?
Aktualizacja
Znalazłem odpowiedź Andersa Hejlsberga na post na forum MSDN na ten temat. On mówi:
Problem, na który natkniesz się, polega na tym, że gdy dwa obiekty są równe, muszą mieć tę samą wartość zwracaną GetHashCode (w przeciwnym razie tabela skrótów używana wewnętrznie przez Distinct nie będzie działać poprawnie). Używamy IEqualityComparer, ponieważ łączy on kompatybilne implementacje Equals i GetHashCode w jednym interfejsie.
Myślę, że to ma sens ...
.Distinct(new KeyEqualityComparer<Customer,string>(c1 => c1.CustomerId))
, i wyjaśnić, dlaczego GetHashCode () jest ważne, aby działać poprawnie.