ucef
ucef

Reputation: 557

Specific Comparer For Distinct

I have to implement specific comparer for Distinct :

public class MyModuleComparer : IEqualityComparer<GenDictionnaireMenu>
{
    

    public bool Equals(GenDictionnaireMenu x, GenDictionnaireMenu y)
    {
        //Check whether the compared objects reference the same data. 
        if (Object.ReferenceEquals(x, y)) return true;

        //Check whether any of the compared objects is null. 
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        return x.LibelleModule == y.LibelleModule;
    }

    public int GetHashCode(GenDictionnaireMenu obj)
    {
        return obj == null ? 0 : (int)obj.CodeDictionnaireMenu;
    }
}

and I use it when I call Distinct like this :

Dim list = ListDictionnaire.Distinct(New MyModuleComparer()).ToList

the problem is that I have the same object having the same LibelleModule in "list" like this :

object1 = code : 1, LibelleModule : "Gestion administrative" , LIBELLE_SOUS_MODULE1: "Congé"

object2 = code : 2, LibelleModule : "Gestion administrative" , LIBELLE_SOUS_MODULE1: "Congé"

object3 = code : 3, LibelleModule : "Gestion administrative" , LIBELLE_SOUS_MODULE1: "Gestion carrière"

please any suggestions!

Upvotes: 1

Views: 89

Answers (1)

ken2k
ken2k

Reputation: 48985

You must provide a different GetHashCode implementation.

Distinct() first calls the light GetHashCode function, and only calls Equals if there is a collision, i.e. if GetHashCode produces the same result for two instances of GenDictionnaireMenu.

Here is the GetHashCode definition:

Two objects that are equal return hash codes that are equal. However, the reverse is not true: equal hash codes do not imply object equality.

That's why Equals is never called (CodeDictionnaireMenu is different for all your instances), and that's why two of your instances are considered to be identical.

EDIT:

Well it's a bit complicated actually. See the MSDN doc for all the details.

One of the main rule is:

If two objects compare as equal, the GetHashCode method for each object must return the same value. However, if two objects do not compare as equal, the GetHashCode methods for the two objects do not have to return different values.

So if your items compare as equal when having the same LibelleModule property, then their hash code should be identical. In your case the hash code is always different even if LibelleModule is the same.

So, one possible hash code could be:

public int GetHashCode(GenDictionnaireMenu obj)
{
    return obj.LibelleModule != null ? obj.LibelleModule.GetHashCode() : 0;
}

Upvotes: 2

Related Questions