2010-03-05 8 views
5

Quando ho iniziato a programmare in C# l'anno scorso, ho immediatamente cercato l'equivalente della mappa di STL e ho imparato a conoscere il dizionario.Qualcuno può spiegare perché Dictionary <> in C# non funziona come la mappa <T,U> in STL?

AGGIORNAMENTO barrato questa spazzatura di seguito, ho sbagliato completamente. La mia esperienza con la mappa di STL era che odiavo quando lo richiedevo per un valore, e se la chiave non era nella mappa, creava automaticamente il tipo di valore (qualunque fosse il suo costruttore predefinito) e lo aggiungeva alla mappa. Dovrei quindi verificare questa condizione nel codice e generare un'eccezione.

Dizionario <> ottiene l'intero shebang corretto - se la chiave non è presente, genera un'eccezione se stai richiedendo il valore, o lo aggiunge automaticamente se non lo è e vuoi impostare il valore.

Ma lo sapevate già tutti. Avrei dovuto scrivere i miei test unitari prima di postare qui e imbarazzarmi. :) Sono scritti ora!

Ora mi piace Dizionario e tutto, ma la cosa che mi bug più su di esso adesso è che se la chiave non è presente nel dizionario, si getta una KeyNotFoundException. Pertanto, ho sempre bisogno di scrivere codice come questo:

Dictionary<string,string> _mydic; 

public string this[string key] 
{ 
    get { 
    return _mydic[key]; // could throw KeyNotFoundException 
    } 
    set { 
    if(_mydic.ContainsKey(key)) 
     _mydic[key] = value; 
    else 
     _mydic.Add(key, value); 
    } 
} 

Perché non a Dizionario automaticamente aggiungere la coppia valore della chiave se la chiave non esiste, come la mappa di STL?

Ora la cosa divertente è che in una vita precedente, ho usato per ottenere infastidito perché avevo spesso devono cercare di evitare mappa da fare proprio questo. Suppongo che i miei casi d'uso adesso siano un po 'diversi.

+5

La mia risposta istintiva sarebbe dovuta al fatto che 'Dictionary ' non è mai stato progettato per replicare la 'mappa STL '. –

+0

Sono sicuro che non lo fosse, ma sono solo curioso del perché hanno deciso di non progettarlo per comportarsi in modo simile in assenza della chiave specificata. – Dave

+0

Penso che tu abbia smarrito alcune istruzioni che dovrebbero essere sul getter all'interno del setter. –

risposta

10

Quale valore si desidera che restituisca se non esistesse già nella mappa? È potrebbe restituire default(TValue) - ma in tal caso sarebbe un po 'facile utilizzare accidentalmente un valore supponendo che fosse corretto. Si noti che se si desidera che il comportamento, è possibile utilizzare:

get { 
    string value; 
    if (!_mydic.TryGetValue(key, out value)) 
    value = default(string); 
    return value; 
} 

io non lo consiglio personalmente in generale, ma se sei felice di non essere in grado di distinguere (tramite questo indicizzatore) tra una chiave con un valore nullo e una chiave mancante, farà il trucco.

Nota che il setter mi può molto più semplice - basta

_mydic[key] = value; 

sovrascriverà se necessario.

+0

Jon, sono un po 'confuso. Il motivo per cui ho tutta questa logica nel setter è a causa dell'eccezione che viene lanciata. Quindi posso usare solo il codice setter che hai specificato se la chiave esiste già ... giusto? – Dave

+2

No - il setter [] aggiungerà o sovrascriverà se necessario. –

+1

@Dave: vedere http://msdn.microsoft.com/en-us/library/9tee9ht2.aspx. "Se la chiave specificata non viene trovata, un'operazione get lancia una KeyNotFoundException, e ** un'operazione set crea un nuovo elemento con la chiave specificata **." –

3

Sono d'accordo nel gestire l'eccezione è un po 'fastidioso, soprattutto per i tipi di riferimento quando ottenere un valore nullo di solito ha senso. In entrambi i casi è possibile utilizzare Dictionary<>.TryGetValue() per ottenere il valore in una chiamata.

+0

Grazie, non avevo mai usato quella chiamata prima. Lo esaminerò! – Dave

0

Sono confuso. Lo fa, qui. Il docs anche dire così:

When you set the property value, if the key is in the Dictionary(TKey, TValue), the value associated with that key is replaced by the assigned value. If the key is not in the Dictionary(TKey, TValue), the key and value are added to the dictionary. 

e

KeyNotFoundException: The property is retrieved and key does not exist in the collection. 

(nessuna menzione di esso che è gettato durante l'assegnazione).

+0

sì mi sono confuso, era il contrario. andando a sistemare il mio post. – Dave

Problemi correlati