using sysCols = System.Collections;
using sysCon = System.Console;
class MainApp{
public static void Main(){
string[] cc = new string[] {"rossi", "verdi", "bianco", "nerone"};
string[] nn = new string[] {"pino", "gino", "nino", "rino"};
sysCols.Hashtable PhoneBook = new sysCols.Hashtable();
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);
}
Person rp = new Person(cc[0], nn[0]);
PhoneBook[rp] = new PhoneNumber(113, 113);
int cnt = 0;
sysCon.WriteLine("#\tNOMINATIVO\t\tNUMERO");
foreach(sysCols.DictionaryEntry pb in PhoneBook)
{
Person p = (Person)pb.Key;
PhoneNumber n = (PhoneNumber)pb.Value;
sysCon.WriteLine("{0}\t{1} {2}\t\t{3}-{4}", ++cnt, p.Nome, p.Cognome, n.Prefisso, n.Numero);
};
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{
private readonly string nome;
private readonly string cognome;
// Per abilitare gli oggetti di tipo Person ad essere utilizzati utilmente come elementi
// key di collezioni (per esempio System.Collections.Hashtable) è necessario fare
// l'override del metodo GetHashCode() e di Equals per implementare il confronto per
// valore.
// In caso contrario, il confronto di default è per riferimento e quindi istanze di
// elementi key di ugale valore risultano comunque diversi.
//
// 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.
//
// (1) è verificata perchè se due oggetti hanno Nome e Cognome uguali, avranno anche lo
// stesso codice Hash; (2) è verificata perch Nome e Cognome vengono assegnati solo nel
// costruttore e mai più modificati; (3)è verificata perchè usa GetHashCode() di string
// che a sua volta non solleva eccezioni; (4) è sicuramente verificata se non faccio
// l'override di Equals perchè Equals di default è per riferimento e quindi fa un
// confronto solo per identità;
//
// Provare a commentare GetHashCode e Equals e notare la difformità di comportamento
public override int GetHashCode() {
return (cognome + nome).GetHashCode();
}
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 || GetType() != obj.GetType()) return false;
Person p = (Person)obj;
return nome == p.nome && cognome == p.cognome;
}
public Person(string nome, string cognome){
this.nome = nome;
this.cognome = cognome;
}
public string Nome{
get {return nome;}
}
public string Cognome{
get {return cognome;}
}
}