TOC

This article is currently in the process of being translated into Italian (~99% done).

Collections:

Dictionaries

I dizionari in C# implementano l'interfaccia IDictionary. Ci sono vari tipi di dizionari, ma i più utilizzati sono i dizionari generici (generic), spesso chiamati Dictionary<TKey, TValue> - i quali contengono una chiave di tipo specifico e un corrispondente valore di tipo specifico. Questo è quello che distingue i dizionari dalle liste: gli oggetti di una lista sono disponibili in un ordine specifico e possono essere acceduti attraverso un indice numerico, mentre gli oggetti di un dizionario sono memorizzati con una chiave unica, che può essere utilizzata successivamente per recuperare l'oggetto.

Vedremo cosa i dizionari possono fare fra poco, per prima cosa guardiamo un semplice esempio, per mostrarti di cosa stiamo parlando:

Dictionary<string, int> users = new Dictionary<string, int>();  
users.Add("John Doe", 42);  
users.Add("Jane Doe", 38);  
users.Add("Joe Doe", 12);  
users.Add("Jenna Doe", 12);

Console.WriteLine("John Doe is " + users["John Doe"] + " years old");

Ti presento la famiglia Doe, che sono nuovamente i dati test per il nostro esempio. Padre,Madre e Gemelli Joe e Jenna. Guarda come ho definito il dizionario per utilizzare la stringa come chiave (in questo caso il nome) e un numero intero come valore (in questo caso l'età). La cosa fantastica e che ci permette di accedere a un oggetto dal dizionario utilizzando la chiave (nome), invece del indice numerico. Puoi vedere questo in azione nell'ultima linea del esempio - in mezzo alle parentesi quadre specifichiamo la chiave per aver accesso al valore (età).

Ci sono due cose importanti da sapere qui: Per prima cosa, la chiave deve essere unica. In questo caso, dove utilìziamo una stringa come chiave, significa che non si possono aggiungere due utenti con lo stesso esatto nome. Questo ha senso, perchè quando si utilizza la chiave per richiamare l'oggetto, la chiave può portare soltanto un valore. D'altro canto questo esempio è un po troppo semplice, perchè ovviamente non puoi avere una collezione di utenti dove nomi duplicati non esistono ma sopportiamolo per il momento.

La seconda cosa da ricordare e che quando si accede il valore da un dizionario, in questo caso la chiave deve esistere nella nostra collezione, quando cerchi di ottenerne il valore. In altre parole, il mio esempio era sicuro perchè ero in pieno controllo di cosa la lista contenga - in molte situazione, dovresti sempre controllare se la chiave esiste prima di utilizzarla, come in questo esempio:

string key = "John Doe";
if(users.ContainsKey(key))
    Console.WriteLine("John Doe is " + users[key] + " years old");

Se provi ad aggiungere una chiave già esistente, o se provi ad avere il valore di una chiave che non esiste, .NET darà un errore. Questo potrebbe sembrare ovvio, ma entrambi sono comunemente trovati nei logs di errori in tutto il mondo.

Lavorare con gli oggetti

Accedere un singolo oggetto può essere molto utile, ma se vuoi ciclare attraverso tutta la collezione e ad esempio trovare qualcosa? In questo caso, la prima cosa che dovresti ricordarti e che gli oggetti della lista non sono oggetti semplici - invece, i dizionari hanno oggetti di tipo KeyValuePair<TKey, TValue>. Le T sono i tipi che hai dichiarato nella lista - in questo caso stringhe e interi. Quindi ciclare attraverso la collezione con un ciclo foreach assomiglierà a questo:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users)
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

La prima cosa che noterai è che ho utilizzato quest'opportunità per cambiare il modo in cui inizializiamo il dizionario - invece di aggiungere manualmente ogni oggetto dopo averlo inizializzato, utiliziamo la sintassi collection initializer, vista nel precedente articolo.

Con questo fuori dai piedi, ora abbiamo lo stesso dizionario di prima - cicliamo attraverso esso. Come puoi vedere, utilizzo il ciclo foreach ed ho dichiarato il tipo di oggetto mi aspetto come KeyValuePair<string, int> - gli stessi due tipi utilizzati per dichiarare il dizionario. Adesso possiamo accedere entrambe i valori, chiave e valore (nome e età) per ogni singolo oggetto, e possiamo utilizzarli per generare una stringa semplice di informazioni della persona per la Console.

L'ordine degli oggetti

L'esempio sopra riportato ci porta a un punto veramente importante: A differenza delle liste, dove l'ordine degli oggetti è determinato dal indice numerico, l'ordine degli oggetti in un dizionario non è determinato, non si può contare sul fatto che gli oggetti siano in un certo ordine, nemmeno quando li aggiungi manualmente. Sicuramente quando esegui l'esempio avrai gli oggetti sempre nello stesso ordine nella quale sono stati aggiunti, ma questa non è una cosa garantita, e quando avrai un dizionario con più oggetti ed inizierai ad aggiungerne e rimuoverne, l'ordine cambierà sicuramente.

la classe Dictionary non possiede un medoto Sort(), perchè alla fine, anche se lo riordini, l'ordine potrebbe cambiare non appena inizi a lavorarci dinuovo. Invece, poi utilizzare i metodi OrderBy() e OrderByDescending() da LINQ (piu informazioni in un altro capitolo) per avere una copia del dizionario riordinata. Questo ti permette anche di riordinare via chiave o valore, che può essere utile nel nostro esempio, per avere gli utenti in ordine per età.

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users.OrderBy(user => user.Value))
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

Se esegui il nostro esempio, vedrai che anche se il dizionario è dichiarato con gli oggetti in un ordine, possiamo facilmente farli uscire in un ordine diverso, come pensiamo sia meglio. Bisogna ricordarsi che siamo responsabili di assicurarci di aver l'oggetto nell'ordine vogliamo, perchè .NET framework li immagazzina come meglio crede.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!