web-dev-qa-db-fra.com

Comment supprimer les doublons de la collection en utilisant IEqualityComparer, LinQ Distinct

Je ne parviens pas à supprimer les doublons de la collection, j'ai implémenté IEqualityComparer pour la classe Employee mais je n'obtiens pas la sortie

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 );
        }

    }

Ci-dessous est l'implémentation de la classe Employee, ici j'ai implémenté 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
}
33
Gun

Oubliez IEqualityComparer et utilisez simplement Linq directement:

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

Voici un bon tutoriel

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

Vous devez remplacer la méthode GetHashCode dans votre employé. Vous ne l'avez pas fait. Un exemple d'une bonne méthode de hachage est donné ci-dessous: (généré par ReSharper )

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

maintenant après l'appel de Distinct, foreach loop imprime:

abc   def
lmn   def

Dans votre cas, vous appelez la classe d'objet GetHashCode, qui ne connaît rien aux champs internes.

Une simple note, MoreLINQ contient DistinctBy méthode d'extension, qui vous permet de faire:

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

Les objets anonymes ont une implémentation correcte pour les méthodes GetHashCode et Equals.

4
Ilya Ivanov

L'implémentation du hashcode n'est pas correcte:

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

Il ressemble également à votre comparaison par référence au lieu de contenu, d'où la fonction de comparaison ne fonctionne pas.

changez-le pour utiliser .Equals () au lieu de == et cela devrait fonctionner. exemple ci-dessous:

#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
0
Arash