Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

[70-536, #10] Implementare le interfacce ICollection, IList e ICloneable

Le interfacce ICollection, IList e ICloneable
Partendo dal codice che abbiamo visto nel post precedente, cominciamo a fare un po' di refactoring e vedere di rendere la nostra classe Shelf aderente ad alcune delle interfacce standard di .NET. Le classi con cui cominceremo sono ICollection, ICloneable e IList. Come abbiamo detto in un post precedente, aderire ad una certa interfaccia (o contract, contratto) significa fornire l'implementazione per ciascuno dei membri previsti dall'interfaccia stessa. La prima cosa da sapere quando dobbiamo fare un lavoro di questo tipo quindi è sapere cosa prevede effettivamente ciascuna interfaccia e scrivere il codice necessario. Cominciamo con ICollection: questa interfaccia prevede tre proprietà (Count, SyncRoot e IsSynchronized) e 1 solo metodo (CopyTo). Se vediamo la documentazione su MSDN2, però, scopriamo che ICollection deriva da IEnumerable, per cui dobbiamo per forza di cose implementare anche quest'ultima interfaccia, che comprende solo il metodo GetEnumerator .

Possiamo quindi far aderire la nostra classe Shelf al contratto previsto da ICollection aggiungendo il codice seguente:

#region "Membri per ICollection"
// Siccome Shelf deve implementare l'interfaccia ICollection
// aggiungo i membri necessari

public int Count
get return (_Contents.Length); } }

public void CopyTo(Array array, int index)
{ }

public object SyncRoot
get return (null); } }

public bool IsSynchronized
get return (true); } }

public IEnumerator GetEnumerator()
{
return (_Contents.GetEnumerator()); }
#endregion

Ed ancora: l'interfaccia ICloneable prevede l'implementazione del solo metodo Clone, che ritorna un duplicato del nostro oggetto Shelf, con gli stessi valori di proprietà. Il codice in questo caso è il seguente:

#region "Membri per ICloneable"
public object 
Clone()
{
    Shelf ret = 
new Shelf(this._Name, this._Contents);
    
return (ret);
}
#endregion

Infine, l'interfaccia IList è un'ulteriore specializzazione di ICollection e richiede i seguenti membri:

// Proprietà
public bool IsReadOnly
public bool IsFixedSize
// Metodi
public int Add(object WhichBook)
public bool Contains(object WhichBook)
public int IndexOf(object WhichBook)
public void Insert(int Position, object WhichBook)
public void Remove(object WhichBook)
public void RemoveAt(int Position)
public object this[int index]

Notare l'ultimo membro this, che ci permette di fare riferimento ad un elemento inserito nello Shelf indicandolo, per esempio, con una sintassi simile alla seguente:

Book mioLibro = (Book) mensola[1];

Ok, deriviamo, usiamo i generics e....via con codice migliore!!!!
Notare il cast che ho fatto in questa istruzione. Notare anche che tutti i membri delle interfacce che abbiamo esaminato hanno come parameter-type un banale, semplice ed inutile object. Questo vuol dire casting continuo, codice poco tipizzato, Intellisense poco utile e via dicendo: tutti quei discorsi che abbiamo già fatto precedentemente trattando i generics. Acceleriamo il discorso: potevamo ottenere lo stesso identico risultato derivando direttamente dalla classe generica List<T>, creando una classe Shelf implementata in questo modo:

class Shelf : List<Book>
{
    
private string _Name;
    
    
public string Name
    {
        
get return _Name; }
        
set { _Name = value; }
    }
    
    
// Costruttori
}

Adesso, la classe Shelf, con sole poche linee di codice, implementa una proprietà Name che serve a noi per il nostro contesto, più tutti i metodi previsti da ICollection e da IEnumerable. Pratico, veloce e comodo, giusto?  Questo rappresenta un utilizzo dei generics: la cosa importante da far notare è che così facendo i metodi Add, Contains, etc. non lavorano su poveri object, ma direttamente su istanze di Book, con un grande vantaggio in termini di.....ok, l'abbiamo già detto!

powered by IMHO 1.2

Print | posted on Wednesday, February 1, 2006 3:16 PM | Filed Under [ Esame 70-536 ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET