2009-03-03 30 views
50

Sto utilizzando un dizionario per eseguire ricerche per un programma su cui sto lavorando. Eseguo un mazzo di chiavi attraverso il dizionario, e mi aspetto che alcune chiavi non abbiano un valore. Prendo lo KeyNotFoundException esattamente dove si trova e lo assorbo. Tutte le altre eccezioni si propagheranno verso l'alto. È questo il modo migliore per gestirlo? O dovrei usare una ricerca diversa? Il dizionario usa un int come chiave e una classe personalizzata come valore.Il modo migliore per gestire un KeyNotFoundException

risposta

88

Uso Dictionary.TryGetValue invece:

Dictionary<int,string> dictionary = new Dictionary<int,string>(); 
int key = 0; 
dictionary[key] = "Yes"; 

string value; 
if (dictionary.TryGetValue(key, out value)) 
{ 
    Console.WriteLine("Fetched value: {0}", value); 
} 
else 
{ 
    Console.WriteLine("No such key: {0}", key); 
} 
+1

bella risposta grazie –

+0

È ancora consigliato questo invece di ContainsKey()? –

+0

@ SvenB: Sì, direi così. Perché la ricerca due volte, una volta per verificare l'esistenza della chiave e poi una volta per ottenere il valore, quando è possibile eseguirli entrambi contemporaneamente? –

31

Provare a utilizzare: Dict.ContainsKey

Edit:
Prestazione saggia penso Dictionary.TryGetValue è meglio come alcuni altri hanno suggerito, ma non mi piace usare quando ho non devo quindi a mio parere ContainsKey è più leggibile ma richiede più righe di codice se è necessario anche il valore.

+0

Perché ha ottenuto un downvote? per favore spiega così posso migliorare la risposta. – Peter

+0

Puoi spiegare perché non ti piace usare 'out' a meno che non sia necessario? –

+1

@wilbishardis è solo un'abitudine, secondo me penso che sia più difficile che un parametro di metodo possa essere modificato molto più chiaramente quando si ha un segno =. ora questa è solo la mia opinione e questo non significa che tutti si sentano uguali, e in alcuni casi la sua migliore opzione 'int.TryParse' è un esempio .. – Peter

4

si dovrebbe utilizzare il 'ContainsKey (tasto string)' il metodo del dizionario per verificare se una chiave esiste. utilizzando le eccezioni per il normale flusso di programma non è considerato una buona pratica.

+2

Esattamente perché ho fatto questa domanda, sentivo che quello che stavo facendo non era una buona pratica. –

11

Qui è un elegante, una soluzione linea (Tenete a mente questo rende la ricerca per due volte. Vedi sotto per la versione TryGetValue di questo che dovrebbe essere utilizzato in cicli di lunga durata.)

string value = dictionary.ContainsKey(key) ? dictionary[key] : "default"; 

Eppure mi trovo a doverlo fare ogni volta che accedo a un dizionario. Io preferirei che tornare nulla così posso solo scrivere:

string value = dictionary[key] ?? "default";//this doesn't work 
+0

Evitare l'uso di questa soluzione in quanto richiede due ricerche sul dizionario. Una ricerca per 'dictionary.ContainsKey' e un'altra per' dictionary [key] '. Usa la risposta di @ JernejNovak per prestazioni migliori. – FrankerZ

+0

A volte le prestazioni non sono una priorità e la leggibilità è più importante. La risposta di Jon Skeet non è qualcosa che vuoi sparsi per tutto il tuo codice. Direi di evitarlo a grandi giri. Prenderò un appunto nella mia risposta. Non vale davvero il downvote però. –

+0

Com'è 'string value = dictionary.ContainsKey (chiave)? dictionary [key]: "default"; 'più leggibile di' string value = dictionary.TryGetValue (chiave, valore out)? valore: "Nessuna chiave!"; ' – FrankerZ

14

Una soluzione line utilizzando TryGetValue

string value = dictionary.TryGetValue(key, out value) ? value : "No key!"; 

essere consapevoli del fatto che valore variabile deve essere di tipo il dizionario rendimenti in questo caso stringa. Qui non è possibile utilizzare var per la dichiarazione delle variabili.

Problemi correlati