Si no desea agregar la biblioteca MoreLinq a su proyecto solo para obtener la DistinctByfuncionalidad, puede obtener el mismo resultado final utilizando la sobrecarga del Distinctmétodo de Linq que toma un IEqualityComparerargumento.
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
peoplecolecció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 Identonces, otro usuario dio la respuesta correcta de que todo lo que necesita hacer es anular las implementaciones predeterminadas de GetHashCode()y Equals()en su Personclase y luego simplemente usar el Distinct()método listo para usar de Linq para filtrar fuera cualquier duplicado.