Se non si desidera aggiungere la libreria MoreLinq al proprio progetto solo per ottenere la DistinctByfunzionalità, è possibile ottenere lo stesso risultato finale utilizzando il sovraccarico del Distinctmetodo di Linq che accetta un IEqualityComparerargomento.
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
peopleraccolta 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 Idallora un altro utente ha dato la risposta corretta che tutto ciò che devi fare è sovrascrivere le implementazioni predefinite di GetHashCode()e Equals()nella tua Personclasse e quindi utilizzare semplicemente il Distinct()metodo predefinito di Linq per filtrare eventuali duplicati.