2017-10-20 30 views
2

J'ai créé deux classes presque identiques. Les deux représentent une paire (x, y) mais dans l'un d'entre eux, j'ai remplacé les méthodes GetHashCode et Equals. On m'a dit que lorsque le HashCode est différent, les Collections les prennent comme des éléments différents et ne prennent même pas la peine de les comparer avec les égaux. Cependant, il s'avère que j'ai implémenté un EqualityComparer pour la classe qui ne remplace pas GetHashCode et Equals et que tout fonctionne correctement même si les HashCodes sont encore différents.Implémentation de EqualityCompare vs remplacement de GetHashCode et égal à

Jetez un oeil à ma console Projet:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace matrixExample 
{ 
    class Program 
    { 

     static void Main(string[] args) 
     { 
      Console.WriteLine("Same Hash but no insertion: as expected"); 
      HashSet<MyPair> hash = new HashSet<MyPair>(); 
      MyPair one = new MyPair { X = 10, Y = 2 }; 
      MyPair copyOfOne = new MyPair { X = 10, Y = 2 }; 
      Console.WriteLine(one.GetHashCode() + " " + hash.Add(one)); 
      Console.WriteLine(copyOfOne.GetHashCode() + " " + hash.Add(copyOfOne)); 


      Console.WriteLine("-----------------------------------------"); 

      Console.WriteLine("Different Hash but no insertion! why?"); 
      HashSet<MyPairWithoutOverride> hash2 = new HashSet<MyPairWithoutOverride>(new SameHash()); 
      MyPairWithoutOverride a1 = new MyPairWithoutOverride { X = 10, Y = 2 }; 
      MyPairWithoutOverride a1copy = new MyPairWithoutOverride { X = 10, Y = 2 }; 
      Console.WriteLine(a1.GetHashCode() + " " + hash2.Add(a1)); 
      Console.WriteLine(a1copy.GetHashCode() + " " + hash2.Add(a1copy)); 

     } 

     public class MyPair 
     { 
      public int X { get; set; } 
      public int Y { get; set; } 

      public override int GetHashCode() 
      { 
       return X * 10000 + Y; 
      } 

      public override bool Equals(object obj) 
      { 
       MyPair other = obj as MyPair; 
       return X == other.X && Y == other.Y; 
      } 
     } 

     public class MyPairWithoutOverride 
     { 
      public int X { get; set; } 
      public int Y { get; set; } 
     } 

     public class SameHash : EqualityComparer<MyPairWithoutOverride> 
     { 
      public override bool Equals(MyPairWithoutOverride p1, MyPairWithoutOverride p2) 
      { 
       return p1.X == p2.X && p1.Y == p2.Y; 
      } 
      public override int GetHashCode(MyPairWithoutOverride i) 
      { 
       return base.GetHashCode(); 
      } 
     } 

    } 
} 

Répondre

3

Votre problème ici est

public override int GetHashCode(MyPairWithoutOverride i) 
{ 
    return base.GetHashCode(); 
} 

Vous êtes de retour base.GetHashCode() qui est en fait le code de hachage de la classe SameHash. Donc, vous renvoyez le même code de hachage à chaque fois.

Si vous renvoyez i.GetHashCode() alors il se comportera comme prévu.

+0

Donc, ce que la Collection est en train de faire, c'est de comparer les hachages de la classe SameHash et c'est pour ça que ça marche quand même. Je l'ai! Merci. – gviot