Question

Se référant à la question que j'ai précédemment posée:Comparez deux listes contenant beaucoup d'objets

Il est impressionnant de voir à quelle vitesse cette comparaison est MAID en mettant en œuvre l'interface iEqualityComparieur: Exemple ici

Comme je l'ai mentionné dans mon autre question, cette comparaison m'aide à sauvegarder un dossier d'esquis dans un dossier de destination. Sachez que je veux me synchroniser avec les dossiers, donc je dois comparer les dates des fichiers. Chaque fois que je fais quelque chose comme:

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            s.dateModified.Date <= d.dateModified.Date;  // This line does not work. 
            // I also tried comparing the strings by converting it to a string and it does
            // not work. It does not give me an error but it does not seem to include the files
            // where s.dateModified.Date < d.dateModified.Date

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (a.compareName.GetHashCode() * 251 + a.size.GetHashCode() * 251 + a.deepness.GetHashCode() + a.dateModified.Date.GetHashCode());

        return rt;

    }
}

Ce sera bien si je pouvais faire quelque chose de similaire en utilisant des signes plus importants ou égaux. J'ai également essayé d'utiliser la propriété Tick et cela ne fonctionne pas. Peut-être que je fais quelque chose de mal. Je pense qu'il n'est pas possible de comparer les choses avec le signe moins que égal implémentant cette interface. De plus, je ne comprends pas comment fonctionne cette classe; Je sais juste que c'est impressionnant à quelle vitesse il itère dans toute la liste.

Était-ce utile?

La solution

Étant donné que les objets DateTime sont différents dans le cas où une datetime est inférieure à l'autre, vous obtenez des codes de hashs différents pour les objets s et et la méthode égale n'est pas appelée. Pour que votre comparaison des dates fonctionne, vous devez supprimer la partie de la date de la méthode Gethashcode:

public int GetHashCode(MyFile a)
{
    int rt = ((a.compareName.GetHashCode() * 251 + a.size.GetHashCode())
                          * 251 + a.deepness.GetHashCode()) *251;

    return rt;

}

Autres conseils

Toute votre approche est fondamentalement défectueuse parce que votre IEqualityComparer.Equals La méthode n'est pas symétrique. Ça signifie Equals(file1, file2) n'est pas égal Equals(file2, file1) En raison de la façon dont vous utilisez l'opérateur moins que.

La documentation:

déclare clairement:

Notes aux exécutants

La méthode égale est réflexive, symétrique et transitive. Autrement dit, il renvoie True s'il est utilisé pour comparer un objet avec lui-même; vrai pour deux objets x et y si c'est vrai pour y et x; et vrai pour deux objets x et z s'il est vrai pour x et y et aussi vrai pour y et z.

Les implémentations sont nécessaires pour s'assurer que si la méthode égale renvoie True pour deux objets x et y, la valeur renvoyée par la méthode GethashCode pour x doit être égale à la valeur renvoyée pour y.

Au lieu de cela, vous devez utiliser le IComparable interface ou IEqualityComparer en combinaison avec les comparaisons des dates. Si vous ne le faites pas, les choses peuvent sembler fonctionner pendant un certain temps, mais vous le regretterez plus tard.

Votre Gethashcode a un problème:

public int GetHashCode(MyFile a)
{
    int rt = (((a.compareName.GetHashCode() * 251) 
           + a.size.GetHashCode() * 251)
           + a.deepness.GetHashCode() *251) 
           + a.dateModified.Date.GetHashCode();

    return rt;

}

J'ai changé la partie de la date car j'avais également besoin du temps, donc j'utilise la propriété Ticks à la place. Je me suis débarrassé du code hachée de DateModified et cela fonctionne très bien. Voici comment j'ai modifié mon programme. J'avais du mal à comparer les dates, donc j'ai utilisé la propriété Ticks.

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            //s.dateModified.Date <= d.dateModified.Date &&
            s.dateModified.Ticks >= d.dateModified.Ticks
            ;  

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (((a.compareName.GetHashCode() * 251)
                + a.size.GetHashCode() * 251)
                + a.deepness.GetHashCode() * 251)
                //+ a.dateModified.Ticks.GetHashCode();                       
                ;

        return rt;

    }
}

Je ne sais toujours pas comment fonctionne cette fonction de code de hachage. La bonne chose est que ça marche très bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top