Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - [C#] Quando utilizzare IEqualityComparer
Forum - C# / VB.NET - [C#] Quando utilizzare IEqualityComparer

Avatar
MillenniumBug (Member)
Rookie


Messaggi: 40
Iscritto: 08/04/2011

Segnala al moderatore
Postato alle 20:30
Domenica, 16/06/2013
Ciao a tutti,

Sto studiando le collezioni in C# e ho visto che per cambiare la modalità con cui vengono comparate le chiavi dei dizionari bisogna utilizzare questa interfaccia e di conseguenza implementare Equals e GetHashCode.
La mia domanda è, perchè devo costruire un comparer personalizzato quando posso fare l'override di Equals e GetHashCode direttamente nella classe che rappresenta la chiave del dizionario?
Esempio:
Codice sorgente - presumibilmente C#

  1. class Customer
  2.     {
  3.         public string name;
  4.         public int age;
  5.         public Customer(string n, int a)
  6.         {
  7.             this.age = a;
  8.             this.name = n;
  9.         }
  10.         public override bool Equals(object obj)
  11.         {
  12.             Customer c = (Customer)obj;
  13.             return this.name == c.name && this.age == c.age;
  14.         }
  15.         public override int GetHashCode()
  16.         {
  17.             return (this.name + ";" + this.age).GetHashCode();
  18.         }
  19.     }
  20. class Program
  21.     {
  22.         static void Main(string[] args)
  23.         {
  24.             Customer c1 = new Customer("MArk", 21);
  25.             Customer c2 = new Customer("MArk", 21);
  26.             Dictionary<Customer, string> d = new Dictionary<Customer, string>();
  27.             Console.WriteLine(c1.Equals(c2));
  28.             try
  29.             {
  30.                 d.Add(c1, "Joe");
  31.                 d.Add(c2, "hil");
  32.                 foreach (KeyValuePair<Customer, string> k in d)
  33.                 {
  34.                     Console.WriteLine(k.Key.name + " ; " + k.Value);
  35.                 }
  36.             }
  37.             catch (ArgumentException)
  38.             {
  39.                 Console.WriteLine("Chiave già inserita in precedenza");
  40.             }
  41.             finally
  42.             {
  43.                 Console.ReadLine();
  44.             }
  45.         }
  46.     }
  47. }


Così mi dice giustamente che la chiave è già stata inserita
Esempio 2:
Codice sorgente - presumibilmente C#

  1. class Customer
  2.     {
  3.         public string name;
  4.         public int age;
  5.         public Customer(string n, int a)
  6.         {
  7.             this.age = a;
  8.             this.name = n;
  9.         }
  10.     }
  11. class DicEqualityComparer : EqualityComparer<Customer>
  12.     {
  13.         public override bool Equals(Customer x, Customer y) // equals dell'equalitycomparer
  14.         {
  15.             return x.name == y.name && x.age == y.age;
  16.         }
  17.         public override int GetHashCode(Customer obj)
  18.         {
  19.             return (obj.name + ";" + obj.age).GetHashCode();
  20.         }
  21.     }
  22.  
  23.     class Program
  24.     {
  25.         static void Main(string[] args)
  26.         {
  27.             Customer c1 = new Customer("MArk", 21);
  28.             Customer c2 = new Customer("MArk", 21);
  29.             DicEqualityComparer dic = new DicEqualityComparer();
  30.             Dictionary<Customer, string> d = new Dictionary<Customer, string>(dic);
  31.             Console.WriteLine(c1.Equals(c2));
  32.             try
  33.             {
  34.                 d.Add(c1, "Joe");
  35.                 d.Add(c2, "hil");
  36.                 foreach (KeyValuePair<Customer, string> k in d)
  37.                 {
  38.                     Console.WriteLine(k.Key.name + " ; " + k.Value);
  39.                 }
  40.             }
  41.             catch (ArgumentException)
  42.             {
  43.                 Console.WriteLine("Chiave già inserita in precedenza");
  44.             }
  45.             finally
  46.             {
  47.                 Console.ReadLine();
  48.             }
  49.         }
  50.     }
  51. }


Stesso risultato quindi ripeto la domanda Quando  e perchè devo usare IEqualityComparer?
Grazie in anticipo.
P.S.: Scusate se il codice non è dei migliori ma l'ho scritto solo come esempio

Ultima modifica effettuata da MillenniumBug il 16/06/2013 alle 20:32


La differenza tra la genialità e la stupidità è che la genialità ha i suoi limiti.
PM Quote
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Segnala al moderatore
Postato alle 10:59
Mercoledì, 03/07/2013
Potrebbe non essere possibile modificare la classe le cui istanze devono essere comparate, oppure potresti voler usare una modalità di comparazione differente da quella nativamente imposta dalla sua dichiarazione. In questi casi è necessario utilizzare un comparer.


"Infelici sono quelli che hanno tanto cervello da vedere la loro stupidità."
(Fligende Blatter)

"Dubitare di se stessi è il primo segno d'intelligenza."
(Ugo Ojetti)
PM Quote