Angella Andrea - Italian Blog

Infinita passione per lo sviluppo software !
posts - 133, comments - 216, trackbacks - 9

My Links

News

MIT OpenCourseWare: I'm invested Wikipedia Affiliate Button


Sto leggendo:

Archives

Post Categories

Siti web realizzati

Siti web tecnici

[70-536] - Generic Collections: List, Dictionary, SortedList, Queue, Stack


Area di riferimento

- Developing applications that use system types and collections
    - Improve type safety and application performance in a .NET Framework application by using generic collections. (Refer System.Collections.Generic namespace)
       - Generic ICollection interface and Generic IList interface 
       - Generic IDictionary interface
       - Generic IEnumerable interface and Generic IEnumerator interface
       - Generic Dictionary class and Generic Dictionary.Enumerator structure
       - Generic Dictionary.KeyCollection class and Dictionary.KeyCollection.Enumerator structure
       - Generic Dictionary.ValueCollection class and Dictionary.ValueCollection.Enumerator structure
       - Generic KeyValuePair structure
       - Generic List class, Generic List.Enumerator structure and Generic SortedList class
       - Generic Queue class and Generic Queue.Enumerator structure
       - Generic Stack class and Generic Stack.Enumerator structure


Generics Collections

Nel post [70-536] - ArrayList class and collection interfaces ho introdotto la classe ArrayList che permette di raggruppare una serie di oggetti che possono essere in seguito acceduti mediante un indice. Siccome questa classe lavora direttamente utilizzando Object il suo utilizzo presenta tutti i problemi che ho illustrato nel post [70-536] - Generic Types. Per questo motivo sfruttando le potenzialità dei Generics è stato definito nel Framework 2.0 il namespace System.Collections.Generic all'interno del quale sono implementate diverse collezioni generiche.

La collezione generica corrispondente ad ArrayList è definita con la classe List<T> che implementa le interfacce ICollection<T>, IEnumerable<T>, IEnumerable.

[TypeDependency("System.SZArrayHelper")]
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
    // Methods
    int IndexOf(T item);
    void Insert(int index, T item);
    void RemoveAt(int index);

    // Properties
    T this[int index] { get; set; }
}

[TypeDependency("System.SZArrayHelper")]
public interface ICollection<T> : IEnumerable<T>, IEnumerable
{
    // Methods
    void Add(T item);
    void Clear();
    bool Contains(T item);
    void CopyTo(T[] array, int arrayIndex);
    bool Remove(T item);

    // Properties
    int Count { get; }
    bool IsReadOnly { get; }
}

public interface IEnumerator<T> : IDisposable, IEnumerator
{
    // Properties
    T Current { get; }
}

// Classe innestata: List.Enumerator
[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
   private List<T> list;
   private int index;
   private int version;
   private T current;
   internal Enumerator(List<T> list);
   public void Dispose();
   public bool MoveNext();
   public T Current { get; }
   object IEnumerator.Current { get; }
   void IEnumerator.Reset();
}


L'utilizzo della collection tuttavia è pressochè identico:

List<int> numeri = new List<int>();
numeri.Add(1);
numeri.Add(2);
numeri.Add(3);

foreach (int i in numeri)
{
    Console.WriteLine(i);
}

List<Studente> studenti = new List<Studente>();  
studenti.Add(new Studente("Andrea"));
studenti.Add(new Studente("Stefano"));
studenti.Add(new Studente("Giorgio"));

foreach (Studente s in studenti)   
{
    Console.WriteLine(s);
}


Esiste una versione generica della classe SortedList che è SortedList<TKey, TValue>. Ecco un esempio di utilizzo:

SortedList<string, int> list = new SortedList<string, int>();
list["Andrea"] = 111111;
list["Stefano"] = 222222;
list["Alessandro"] = 333333;

foreach (KeyValuePair<string, int> entry in list)
{
    Console.WriteLine("Lo studente {0} è la matricola {1}", entry.Key, entry.Value);
}

int i = list.IndexOfKey("Andrea");
Console.WriteLine("Lo studente {0} è la matricola {1}", list.Keys[i], list.Values[i]);


La classe KeyValuePair<TKey, TValue> rappresenta un elemento di un dizionario cioè una coppia chiave/valore e corrisponde alla classe DictionaryEntry nel caso di SortedList e Hashtable.

Nel mondo dei generics la classe Hashtable è chiamata Dictionary<TKey, TValue> e implementa le interfacce IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, ICollection, IEnumerable.

public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable
{
    // Methods
    void Add(TKey key, TValue value);
    bool ContainsKey(TKey key);
    bool Remove(TKey key);
    bool TryGetValue(TKey key, out TValue value);

    // Properties
    TValue this[TKey key] { get; set; }
    ICollection<TKey> Keys { get; }
    ICollection<TValue> Values { get; }
}

// Classe innestata: Dictionary.Enumerator

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct Enumerator : IEnumerator<KeyValuePair<TKey, TValue>>, IDisposable, IDictionaryEnumerator, IEnumerator
{
    internal const int DictEntry = 1;
    internal const int KeyValuePair = 2;
    private Dictionary<TKey, TValue> dictionary;
    private int version;
    private int index;
    private KeyValuePair<TKey, TValue> current;
    private int getEnumeratorRetType;
    internal Enumerator(Dictionary<TKey, TValue> dictionary, int getEnumeratorRetType);
    public bool MoveNext();
    public KeyValuePair<TKey, TValue> Current { get; }
    public void Dispose();
    object IEnumerator.Current { get; }
    void IEnumerator.Reset();
    DictionaryEntry IDictionaryEnumerator.Entry { get; }
    object IDictionaryEnumerator.Key { get; }
    object IDictionaryEnumerator.Value { get; }
}


Ecco un esempio di utilizzo della classe Dictionary<TKey, TValue>:

Dictionary<string, int> list = new Dictionary<string, int>();
list["Andrea"] = 111111;
list["Stefano"] = 222222;
list["Alessandro"] = 333333;

foreach (KeyValuePair<string, int> entry in list)
{
    Console.WriteLine("Lo studente {0} è la matricola {1}", entry.Key, entry.Value);
}


Come potete immaginare esistono anche le versioni generiche delle strutture dati Stack e Queue.
Queste classi sono Queue<T> e Stack<T> e si utilizzano in modo analogo:

Stack<string> stack = new Stack<string>();

stack.Push("Andrea");             // Inserimento in testa alla pila
stack.Push("Franco");
stack.Push("Annamaria");

Console.WriteLine(stack.Peek());  // Legge la testa della pila senza estrarre l'elemento
Console.WriteLine(stack.Pop());   // Estrazione di un elemento dalla testa della pila
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Pop());

Queue<string> queue = new Queue<string>();

queue.Enqueue("Andrea");              // Inserimento in coda
queue.Enqueue("Franco");
queue.Enqueue("Annamaria");

Console.WriteLine(queue.Peek());      // Legge il primo elemento della coda senza estrarlo
Console.WriteLine(queue.Dequeue());   // Estrae il primo elemento inserito nella coda
Console.WriteLine(queue.Dequeue());
Console.WriteLine(queue.Dequeue());


I vantaggi che offrono i generics sono indiscutibili, quindi è opportuno se possibile utilizzare sempre le collezioni generiche perchè garantiscono la sicurezza del tipo, rendono il codice più pulito e migliorano le performance. Inoltre il modello a oggetti di queste classi è stato rivisto e migliorato rispetto alle collection tradizionali.

Print | posted on sabato 17 novembre 2007 02:52 | Filed Under [ Exam 70-536 Application Development Foundation ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET