c# linq list

linq c# distinct lambda



Cómo eliminar duplicados de la colección utilizando IEqualityComparer, LinQ Distinct (6)

Aquí hay un buen tutorial

public int GetHashCode(Employe obj) { return obj.fname.GetHashCode() ^ obj.lname.GetHashCode(); }

No puedo eliminar los duplicados de la colección, he implementado IEqualityComparer para la clase Employee todavía no obtengo la salida

static void Main(string[] args) { List<Employe> Employeecollection = new List<Employe>(); Employeecollection.Add(new Employe("abc","def")); Employeecollection.Add(new Employe("lmn","def")); Employeecollection.Add(new Employe("abc", "def")); IEnumerable<Employe> coll = Employeecollection.Distinct(new Employe()); foreach (Employe item in coll) { Console.WriteLine(item.fName + " " + item.lName ); } }

La siguiente es la implementación de la clase Employee, aquí implementé IEqualityComparer

class Employe : IEqualityComparer<Employe> { public string fName { get; set; } public string lName { get; set; } public Employe() { } public Employe(string firstName, string LastName) { this.fName = firstName; this.lName = LastName; } #region IEqualityComparer<pcf> Members public bool Equals(Employe x, Employe y) { if (x.fName == y.fName && x.lName == y.lName) { return true; } return false; } public int GetHashCode(Employe obj) { return obj.GetHashCode(); } #endregion }


La implementación de hashcode no es correcta:

public override int GetHashCode() { return 13 * fName.GetHashCode() + 7 * lName.GetHashCode(); }


Olvídese de IEqualityComparer y simplemente use Linq directamente:

EmployeeCollection.GroupBy(x => new{x.fName, x.lName}).Select(g => g.First());


GetHashCode anular el método GetHashCode en su Empleado. No has hecho esto Un ejemplo de un buen método de hashing se da a continuación: (generado por ReSharper )

public override int GetHashCode() { return ((this.fName != null ? this.fName.GetHashCode() : 0) * 397) ^ (this.lName != null ? this.lName.GetHashCode() : 0); }

ahora después de llamar a Distinct , se imprime el bucle foreach:

abc def lmn def

En su caso, está llamando a GetHashCode la clase GetHashCode , que no sabe nada sobre los campos internos.

Una nota simple, MoreLINQ contiene el método de extensión DistinctBy , que le permite hacer:

IEnumerable<Employe> coll = Employeecollection.DistinctBy(employee => new {employee.fName, employee.lName});

Los objetos anónimos tienen una implementación correcta para los métodos GetHashCode y Equals .


public int GetHashCode(Employe obj) { return obj.GetHashCode(); }

Para este método, devuelve un código hash de las propiedades que estás comparando para la igualdad, en lugar del objeto mismo. La comparación del código hash de los objetos siempre será false , por lo que su lista nunca se filtrará por duplicados.


También parece que su comparación por referencia en lugar de contenido, por lo tanto, la función de comparación no funciona.

cámbielo para usar .Equals () en lugar de == y debería funcionar. ejemplo a continuación:

#region IEqualityComparer<pcf> Members public bool Equals(Employe x, Employe y) { if (x.fName.Equals(y.fName) && x.lName.Equals(y.lName)) { return true; } return false; } public int GetHashCode(Employe obj) { return obj.GetHashCode(); } #endregion