Si no desea agregar la biblioteca MoreLinq a su proyecto solo para obtener la DistinctBy
funcionalidad, puede obtener el mismo resultado final utilizando la sobrecarga del Distinct
método de Linq que toma un IEqualityComparer
argumento.
Comienza creando una clase de comparación de igualdad personalizada genérica que utiliza la sintaxis lambda para realizar una comparación personalizada de dos instancias de una clase 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);
}
}
Luego, en su código principal, lo usa así:
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! :)
Lo anterior supone lo siguiente:
- Propiedad
Person.Id
es de tipoint
- La
people
colección no contiene ningún elemento nulo.
Si la colección podría contener nulos, simplemente reescriba las lambdas para verificar si hay nulos, por ejemplo:
Func<Person, Person, bool> areEqual = (p1, p2) =>
{
return (p1 != null && p2 != null) ? int.Equals(p1.Id, p2.Id) : false;
};
EDITAR
Este enfoque es similar al de la respuesta de Vladimir Nesterovsky pero más simple.
También es similar al de la respuesta de Joel, pero permite una lógica de comparación compleja que involucra múltiples propiedades.
Sin embargo, si sus objetos solo pueden diferir para Id
entonces, otro usuario dio la respuesta correcta de que todo lo que necesita hacer es anular las implementaciones predeterminadas de GetHashCode()
y Equals()
en su Person
clase y luego simplemente usar el Distinct()
método listo para usar de Linq para filtrar fuera cualquier duplicado.