Oppure

Loading
16/06/13 18:30
MillenniumBug
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:
  class Customer
    {
        public string name;
        public int age;
        public Customer(string n, int a)
        {
            this.age = a;
            this.name = n;
        }
        public override bool Equals(object obj)
        {
            Customer c = (Customer)obj;
            return this.name == c.name && this.age == c.age;
        }
        public override int GetHashCode()
        {
            return (this.name + ";" + this.age).GetHashCode();
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            Customer c1 = new Customer("MArk", 21);
            Customer c2 = new Customer("MArk", 21);
            Dictionary<Customer, string> d = new Dictionary<Customer, string>();
            Console.WriteLine(c1.Equals(c2));
            try
            {
                d.Add(c1, "Joe");
                d.Add(c2, "hil");
                foreach (KeyValuePair<Customer, string> k in d)
                {
                    Console.WriteLine(k.Key.name + " ; " + k.Value);
                }
            }
            catch (ArgumentException)
            {
                Console.WriteLine("Chiave già inserita in precedenza");
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }
}

Così mi dice giustamente che la chiave è già stata inserita
Esempio 2:
class Customer
    {
        public string name;
        public int age;
        public Customer(string n, int a)
        {
            this.age = a;
            this.name = n;
        }
    }
class DicEqualityComparer : EqualityComparer<Customer>
    {
        public override bool Equals(Customer x, Customer y) // equals dell'equalitycomparer
        {
            return x.name == y.name && x.age == y.age;
        }
        public override int GetHashCode(Customer obj)
        {
            return (obj.name + ";" + obj.age).GetHashCode();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Customer c1 = new Customer("MArk", 21);
            Customer c2 = new Customer("MArk", 21);
            DicEqualityComparer dic = new DicEqualityComparer();
            Dictionary<Customer, string> d = new Dictionary<Customer, string>(dic);
            Console.WriteLine(c1.Equals(c2));
            try
            {
                d.Add(c1, "Joe");
                d.Add(c2, "hil");
                foreach (KeyValuePair<Customer, string> k in d)
                {
                    Console.WriteLine(k.Key.name + " ; " + k.Value);
                }
            }
            catch (ArgumentException)
            {
                Console.WriteLine("Chiave già inserita in precedenza");
            }
            finally
            {
                Console.ReadLine();
            }
        }
    }
}

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 16/06/13 18:32
aaa
03/07/13 8:59
Il Totem
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.
aaa