La classe Dictionary di C#
La classe Dictionary, contenuta nel namespace System.Collections.Generic, rappresenta una collezione di chiavi-valori.
Essendo implementata come una tabella hash, ottenere un valore a partire da una chiave ha complessità vicina O(1) (dipende comunque anche dalla qualità dell’algoritmo di hash definito per il tipo chiave).
Dictionary una classe generica, ed è dunque necessario specificare la classe della chiave e quella del valore:
using System; using System.Collections.Generic; namespace test { class MainClass { public static void Main (string[] args) { Dictionary<String, String> dict = new Dictionary<String, String>(); } } }
L’aggiunta di una coppia avviene utilizzando il metodo:
public void Add( TKey key, TValue value )
Ad esempio:
using System; using System.Collections.Generic; namespace test { class MainClass { public static void Main (string[] args) { Dictionary<String, String> dict = new Dictionary<String, String>(); dict.Add("firstname", "Mario"); dict.Add("lastname", "Rossi"); dict.Add("age", "23"); dict.Add("city", "Roma"); } } }
La rimozione di un elemento avviene con il metodo:
public bool Remove( TKey key )
Come è intuibile, il metodo ritorna false se non c’è nessuna coppia chiave-valore con la chiave specificata, true altrimenti.
using System; using System.Collections.Generic; namespace test { class MainClass { public static void Main (string[] args) { Dictionary<String, String> dict = new Dictionary<String, String>(); dict.Add("firstname", "Mario"); dict.Add("lastname", "Rossi"); dict.Add("age", "23"); dict.Add("city", "Roma"); dict.Add("other1", ""); bool removed = dict.Remove("other1"); Console.WriteLine("Key 'other1' removed? {0}\n", removed); } } }
Accedere ai valori di un dizionario può esser fatto in diversi modi, ad esempio utilizzando uno dei due metodi seguenti:
public TValue this[ TKey key ] { get; set; } public bool TryGetValue( TKey key, out TValue value )
Il primo lancia un KeyNotFoundException se la chiave non è presente, il secondo ritorna false invece:
using System; using System.Collections.Generic; namespace test { class MainClass { public static void Main (string[] args) { Dictionary<String, String> dict = new Dictionary<String, String>(); dict.Add("firstname", "Mario"); dict.Add("lastname", "Rossi"); dict.Add("age", "23"); dict.Add("city", "Roma"); try { Console.WriteLine(dict["no"]); } catch(KeyNotFoundException ex) { Console.WriteLine(ex.Message); } String outStr; bool found = dict.TryGetValue("firstname", out outStr); if(found) { Console.WriteLine(outStr); } else { Console.WriteLine("Chiave non presente"); } } } }
Anche iterare attraverso un dizionario può essere fatto in diversi modi.
Di seguito sfrutteremo un oggetto KeyValuePair, il foreach e l’Enumerator:
using System; using System.Collections.Generic; namespace test { class MainClass { public static void Main (string[] args) { Dictionary<String, String> dict = new Dictionary<String, String>(); dict.Add("firstname", "Mario"); dict.Add("lastname", "Rossi"); dict.Add("age", "23"); dict.Add("city", "Roma"); Dictionary<String, String>.KeyCollection keys = dict.Keys; Console.WriteLine(">> Modo 1 <<\n"); foreach(String key in keys) { Console.WriteLine("{0} = {1}", key, dict[key]); } Console.WriteLine("\n>> Modo 2 <<\n"); foreach(KeyValuePair<String, String> kvp in dict) { Console.WriteLine("{0} = {1}", kvp.Key, kvp.Value); } // // equivalente a // Dictionary<String, String>.Enumerator en = dict.GetEnumerator(); Console.WriteLine("\n>> Modo 3 <<\n"); while(en.MoveNext()) { KeyValuePair<String, String> kvp = en.Current; Console.WriteLine("{0} = {1}" , kvp.Key, kvp.Value); } } } }
Output (su macchina linux con Mono):
anto@anto-net:~/Documenti/Projects/test/test$ gmcs Main.cs anto@anto-net:~/Documenti/Projects/test/test$ mono Main.exe >> Modo 1 << firstname = Mario lastname = Rossi age = 23 city = Roma >> Modo 2 << firstname = Mario lastname = Rossi age = 23 city = Roma >> Modo 3 << firstname = Mario lastname = Rossi age = 23 city = Roma