Se você não quiser adicionar a biblioteca MoreLinq ao seu projeto apenas para obter a DistinctBy
funcionalidade, poderá obter o mesmo resultado final usando a sobrecarga do Distinct
método Linq que leva umIEqualityComparer
argumento.
Você começa criando uma classe comparadora de igualdade customizada genérica que usa a sintaxe lambda para executar a comparação customizada de duas instâncias de uma classe genérica:
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);
}
}
Então, no seu código principal, você o usa da seguinte maneira:
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));
Voila! :)
O acima pressupõe o seguinte:
- Propriedade
Person.Id
é do tipoint
- A
people
coleção não contém nenhum elemento nulo
Se a coleção puder conter nulos, basta reescrever as lambdas para verificar se há nulos, por exemplo:
Func<Person, Person, bool> areEqual = (p1, p2) =>
{
return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};
EDITAR
Essa abordagem é semelhante à da resposta de Vladimir Nesterovsky, mas mais simples.
Também é semelhante ao da resposta de Joel, mas permite uma lógica de comparação complexa envolvendo várias propriedades.
No entanto, se seus objetos só puderem diferir, Id
então outro usuário deu a resposta correta de que tudo que você precisa fazer é substituir as implementações padrão de GetHashCode()
e Equals()
na sua Person
classe e, em seguida, basta usar o Distinct()
método pronto para uso do Linq para filtrar quaisquer duplicatas.