2017-10-20 2 views
2

Ich habe zwei fast identische Klassen erstellt. Beide repräsentieren ein Paar (x, y), aber in einem von ihnen überschrieb ich die Methoden GetHashCode und Equals. Mir wurde gesagt, dass die Sammlungen, wenn der HashCode anders ist, sie als verschiedene Elemente verwenden und sich nicht einmal darum bemühen, sie mit den Gleichen zu vergleichen. Es stellt sich jedoch heraus, dass ich einen EqualityComparer für die Klasse implementiert habe, der GetHashCode und Equals nicht überschreibt und alles funktioniert, auch wenn die HashCodes noch unterschiedlich sind.Implementieren EqualityCompare vs überschreiben GetHashCode und Gleich

Werfen Sie einen Blick auf meine Konsole Projekt:

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

    } 
} 

Antwort

3

Ihr Problem

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

hier sind Sie base.GetHashCode() Rückkehr, die eigentlich der Hash-Code der SameHash Klasse. Sie geben also jedes Mal denselben Hash-Code zurück.

Wenn Sie i.GetHashCode() zurückgeben, verhält es sich wie erwartet.

+0

Also, was die Sammlung tatsächlich tut, vergleicht die Hashes der SameHash-Klasse und deshalb funktioniert es trotzdem. Ich habs! Vielen Dank. – gviot

Verwandte Themen