using sysCols = System.Collections;
using sysCon = System.Console;
using sysDia = System.Diagnostics;
class MainApp{
public static void Main(){
string[] cc = new string[] {"rossi", "Verdi", "bianco", "Nerone"};
string[] nn = new string[] {"pino", "gino", "nino", "rino", "Pino", "GINO", "Gino"};
// Dichiaro e popolo la collezione PhoneBook di tipo SortedList
System.Collections.SortedList PhoneBook = new System.Collections.SortedList();
for ( int i = cc.GetLowerBound(0); i <= cc.GetUpperBound(0); i++ )
for ( int j = nn.GetLowerBound(0); j <= nn.GetUpperBound(0); j++ )
{
Person key = new Person(cc[i], nn[j]);
PhoneNumber item = new PhoneNumber(0431 + i, 123450 + (10*i) + j);
PhoneBook.Add(key, item);
}
// Visito la collezione ordinata secondo il criterio espresso dagli elementi
// di tipo Key (Person)
sysCon.WriteLine("NOMINATIVO\tNUMERO TEL.");
foreach(sysCols.DictionaryEntry pb in PhoneBook)
{
Person p = (Person)pb.Key;
PhoneNumber n = (PhoneNumber)pb.Value;
sysCon.WriteLine("{0} {1}\t{2}-{3}", p.Cognome, p.Nome, n.Prefisso.ToString("0###"), n.Numero);
};
// Confronto alcuni elementi
sysCon.WriteLine("\n\nPerson(\"Di Tacco\", \"Gino\").Equals(Person(\"Guatenalbare\", \"Petrocle\")): {0}",
(new Person("Di Tacco", "Gino")).Equals(new Person("Guatenalbare", "Petrocle")));
sysCon.WriteLine("Person(\"Di Tacco\", \"Gino\").Equals(Person(\"Di Tacco\", \"Gino\")): {0}",
(new Person("Di Tacco", "Gino")).Equals(new Person("Di Tacco", "Gino")));
sysCon.WriteLine("\nPerson(\"Di Tacco\", \"Gino\") == Person(\"Di Tacco\", \"Gino\"): {0}",
(new Person("Di Tacco", "Gino")) == (new Person("Di Tacco", "Gino")));
sysCon.WriteLine("Person(\"Di Tacco\", \"Gino\") != Person(\"Di Tacco\", \"Gino\"): {0}",
(new Person("Di Tacco", "Gino")) != (new Person("Di Tacco", "Gino")));
sysCon.WriteLine("\nPerson(\"Guatenalbare\", \"Petrocle\") == Person(\"Guatenalbare\", \"PETROCLE\"): {0}",
(new Person("Guatenalbare", "Petrocle")) == (new Person("Guatenalbare", "PETROCLE")));
// Visualizzo alcuni codici hash
sysCon.WriteLine("\nnew Person(\"Guatenalbare\", \"Petrocle\").GetHashcode(): {0}",
(new Person("Guatenalbare", "Petrocle")).GetHashCode());
sysCon.WriteLine("new Person(\"Guatenalbare\", \"Petrocle\").GetHashcode(): {0}",
(new Person("Guatenalbare", "Petrocle")).GetHashCode());
return;
}
}
class PhoneNumber{
private int prefisso;
private int numero;
public PhoneNumber(int prefisso, int numero){
this.prefisso = prefisso;
this.numero = numero;
}
public int Prefisso{
get{return prefisso;}
}
public int Numero{
get{return numero;}
}
}
class Person: System.IComparable {
private readonly string nome;
private readonly string cognome;
public Person(string cognome, string nome){
this.cognome = cognome;
this.nome = nome;
}
public string Cognome{
get {return cognome;}
}
public string Nome{
get {return nome;}
}
// Per abilitare gli oggetti di tipo Person ad essere utilizzati come elementi key
// di collezioni con ordinamento (per esempio System.Collections.SortedList) è necessario
// implementare l'interfaccia IComparable.
//
// IComparable.CompareTo(object obj) Return Value Meaning
// a) Less than zero This instance is less than obj.
// b) Zero This instance is equal to obj.
// c) Greater than zero This instance is greater than obj.
//
// d) By definition, any object compares greater than a null reference; and two null
// references compare equal to each other.
// e) The parameter, obj, must be the same type as the class or value type that implements
// this interface; otherwise, an ArgumentException is thrown.
//
// For any objects A, B and C, the following must be true:
// f) A.CompareTo(A) is required to return zero.
// g) If A.CompareTo(B) returns zero then B.CompareTo(A) is required to return zero.
// h) If A.CompareTo(B) returns zero and B.CompareTo(C) returns zero then
// A.CompareTo(C) is required to return zero.
// i)If A.CompareTo(B) returns a value other than zero then B.CompareTo(A) is required to
// return a value of the opposite sign.
// j) If A.CompareTo(B) returns a value x not equal to zero, and B.CompareTo(C) returns
// a value y of the same sign as x, then A.CompareTo(C) is required to return a value
// of the same sign as x and y.
int System.IComparable.CompareTo(object obj)
{
if (obj == (object)this) return 0; // (f)
if (this.GetType() != obj.GetType()) throw new System.ArgumentException(); // (e)
if (obj == null) return +1; // (d)
sysDia.Debug.Assert(GetType() == obj.GetType() && obj != null);
string a = this.cognome + "-" + this.nome;
Person p = (Person)obj;
string b = p.cognome + "-" + p.nome;
return a.CompareTo(b); // (a) (b) (c) (g) (h) (i) (j)
}
// Per l'Ordinamento viene utilizzata l'interfaccia IComparable mentre per testare
// l'ugualianza (in generale, non dalla collezione) viene utilizzato il metodo Equals.
// IComparable e Equals devono operare coerentemente. Quindi la classe che implementa
// IComparable deve fare l'override di Equals.
public override bool Equals(object obj) {
if (obj == (object)this) return true;
//Check for null and compare run-time types (quello della classe della istanza).
if (obj == null || this.GetType() != obj.GetType()) return false;
Person p = (Person)obj;
return this.cognome == p.cognome && this.nome == p.nome;
}
// La classe che fa l'override di Equals deve fare l'override di GetHashCode coerentemente.
//
// 1 If two objects of the same type represent the same value, the hash function must
// return the same constant value for either object.
// 2 A hash function should be based on an immutable data member. The hash function should
// return exactly the same value regardless of any changes that are made to the object.
// Basing the hash function on a mutable data member can cause serious problems, including
// never being able to access that object in a hash table
// 3 Implementations of GetHashCode must not throw exceptions
// 4 Derived classes that override GetHashCode must also override Equals to guarantee that
// two objects considered equal have the same hash code;
// 5 For the best performance, a hash function should generate a random distribution
// for all input.
public override int GetHashCode() {
return (cognome + "-" + nome).GetHashCode();
}
}