IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

Création d'un hashCode avec deux paramètres


Sujet :

Framework .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    849
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 849
    Par défaut Création d'un hashCode avec deux paramètres
    Bonjour,

    J'ai une class avec deux propriétés "clés" A(long?) et B (string) et d'autres propriétés
    Pour faire des comparaisons avec des list j'utilise IEqualityComparer

    La comparaison se fait sur A et B. Si au moins un des éléments A ou B est identique alors l'objet est identique.

    Or mon problème vient du HashCode. Il faut lorsque A et B même différent retourne le même hash, pour être comparer. Avez-vous une idée ?

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace ConsoleApplication3
    {
        class Program
        {
            static void Main(string[] args)
            {
                var objA = new Toto { A = 45, B = "X" };
                var objB = new Toto { A = 4, B = "D" };
                var objC = new Toto { A = 5, B = "X" };
                var objD = new Toto { A = 45, B = "A" };
     
                WriteToto(objA);
                WriteToto(objB);
                WriteToto(objC);
                WriteToto(objD);
     
                //Ne doit retourner que des TRUE
                Console.WriteLine(objA.GetHashCode() == objB.GetHashCode());
                Console.WriteLine(objA.GetHashCode() != objC.GetHashCode());
                Console.WriteLine(objA.GetHashCode() == objC.GetHashCode());
                Console.WriteLine(objA.GetHashCode() == objD.GetHashCode());
     
                var listA = new List<Toto>();
                var listB = new List<Toto>();
     
                listA.Add(objA);
                listA.Add(objB);
                listA.Add(objC);
                listA.Add(objD);
     
                listB.Add(objA);
     
                var list = listA.Intersect(listB, new TotoComparer()).ToList();
                //Normalement je devrai récuperer A, C, D
                Console.WriteLine(list.Count == 3);
                Console.WriteLine(list.Contains(objA));
                Console.WriteLine(list.Contains(objC));
                Console.WriteLine(list.Contains(objD));
     
                list = listA.Except(listB, new TotoComparer()).ToList();
                //Normalement je devrai récuperer B
                Console.WriteLine(list.Count == 1);
                Console.WriteLine(list.Contains(objB));
                Console.ReadLine();
            }
     
            public static void WriteToto(Toto t)
            {
                Console.WriteLine(t.ToString() + " " + t.GetHashCode());
            }
        }
     
        public class Toto
        {
            public long? A { get; set; }
            public string B { get; set; }
     
            public string C { get; set; }
     
            public override string ToString()
            {
                return base.ToString();
            }
     
            public override int GetHashCode()
            {
                //hash code à faire
                return A.GetHashCode();
            }
        }
     
        public class TotoComparer : IEqualityComparer<Toto>
        {
            public bool Equals(Toto x, Toto y)
            {
                return
                    (
                        (x.A.HasValue) && (x.A == y.A)
                     ||
                        (x.B == y.B)
                        )
     
     
                    ;
            }
     
            public int GetHashCode(Toto obj)
            {
                return obj.GetHashCode();
            }
        }
    }


    Merci beaucoup de votre aide

  2. #2
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    A priori la seule solution est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public override int GetHashCode()
    {
        //hash code à faire
        return 0;
    }
    Concernant le résultat final seule compte l'égalité.
    Le hash code est une optimisation, notamment dans le cadre des hash maps.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    849
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 849
    Par défaut
    Le problème c'est que dans mon vrai cas, j'ai des deux list avec 10000 élements, et la comparaison met beaucoup de temps. D'où le hash

  4. #4
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Si tu fais ce type d'opérations ensemblistes essaye en stockant tes objets dans des Dictionary et utilise un hash "normal" du coup :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public override int GetHashCode()
    {
        //hash code à faire
        return (A ?? 0).GetHashCode() ^ (B ?? "").GetHashCode() ^ (C ?? "").GetHashCode();
    }
    Il y a des fonctions de hash avec de meilleures caractéristiques statistiques mais teste déjà avec ça.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    849
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 849
    Par défaut
    Le hash de l'objet C, n'est pas bon.

  6. #6
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    C'est à dire ?

    Si pour ta comparaison spécifique tu n'utilises pas C alors en effet tu peux changer dans l'IEqualityComparer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public int GetHashCode(Toto obj)
    {
        return (obj.A ?? "").GetHashCode() ^ (obj.B ?? "").GetHashCode();
    }

Discussions similaires

  1. Réponses: 8
    Dernier message: 10/12/2007, 16h27
  2. [Visual Web] Query avec deux paramètres
    Par eponette dans le forum NetBeans
    Réponses: 1
    Dernier message: 19/03/2007, 13h44
  3. [MySQL] La pagination avec deux paramètres
    Par arti2004 dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 05/10/2006, 14h25
  4. Réponses: 3
    Dernier message: 28/04/2006, 10h17
  5. Procédure stockée avec deux paramètres ADO/ORACLE
    Par zanifu dans le forum Bases de données
    Réponses: 7
    Dernier message: 01/03/2006, 09h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo