Se non si desidera aggiungere la libreria MoreLinq al proprio progetto solo per ottenere la DistinctBy
funzionalità, è possibile ottenere lo stesso risultato finale utilizzando il sovraccarico del Distinct
metodo di Linq che accetta un IEqualityComparer
argomento.
Si inizia creando una classe di confronto di uguaglianza personalizzata generica che utilizza la sintassi lambda per eseguire il confronto personalizzato di due istanze di una classe generica:
public class CustomEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> _comparison;
Func<T, int> _hashCodeFactory;
public CustomEqualityComparer(Func<T, T, bool> comparison, Func<T, int> hashCodeFactory)
{
_comparison = comparison;
_hashCodeFactory = hashCodeFactory;
}
public bool Equals(T x, T y)
{
return _comparison(x, y);
}
public int GetHashCode(T obj)
{
return _hashCodeFactory(obj);
}
}
Quindi nel tuo codice principale lo usi in questo modo:
Func<Person, Person, bool> areEqual = (p1, p2) => int.Equals(p1.Id, p2.Id);
Func<Person, int> getHashCode = (p) => p.Id.GetHashCode();
var query = people.Distinct(new CustomEqualityComparer<Person>(areEqual, getHashCode));
Ecco! :)
Quanto sopra presuppone quanto segue:
- La proprietà
Person.Id
è di tipoint
- La
people
raccolta non contiene alcun elemento null
Se la raccolta potrebbe contenere valori null, riscrivi semplicemente i lambdas per verificare la presenza di null, ad esempio:
Func<Person, Person, bool> areEqual = (p1, p2) =>
{
return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};
MODIFICARE
Questo approccio è simile a quello nella risposta di Vladimir Nesterovsky, ma più semplice.
È anche simile a quello nella risposta di Joel, ma consente una complessa logica di confronto che coinvolge più proprietà.
Tuttavia, se i tuoi oggetti possono differire solo da Id
allora un altro utente ha dato la risposta corretta che tutto ciò che devi fare è sovrascrivere le implementazioni predefinite di GetHashCode()
e Equals()
nella tua Person
classe e quindi utilizzare semplicemente il Distinct()
metodo predefinito di Linq per filtrare eventuali duplicati.