2010-01-26 9 views

risposta

138

Supponendo che si desidera ottenere il valore se la chiave fa esiste, utilizzare Dictionary<TKey, TValue>.TryGetValue:

int value; 
if (dictionary.TryGetValue(key, out value)) 
{ 
    // Key was in dictionary; "value" contains corresponding value 
} 
else 
{ 
    // Key wasn't in dictionary; "value" is now 0 
} 

(Usando ContainsKey e poi il l'indicizzatore lo fa apparire la chiave due volte, il che è abbastanza inutile.)

si noti che, anche se si erano utilizzando tipi di riferimento, il controllo di nulla non avrebbe funzionato - l'indicizzatore per Dictionary<,> un'eccezione se si richiede una chiave mancante, invece di ritornare null. (Questa è una grande differenza tra Dictionary<,> e Hashtable.)

+0

@JonSkeet Non è TryGetValue che esegue anche una doppia ricerca ([come indicato nel corpo di questa domanda] (http://stackoverflow.com/questions/1413304/net-adding-dictionary-item-check-if-it-exists- o-lasciare-eccezione))? – nawfal

+2

@nawfal: Non vedo alcuna indicazione che quella domanda lo affermi affatto. Dice che sta facendo più lavoro di 'ContainsKey', che è vero, perché deve estrarre anche il valore. Comunque non sta facendo due ricerche. –

+0

Ingenuamente, ho continuato a prevedere nulla, ma per Dizionario , restituisce l'equivalente "0" nell'enumerazione. – Jess

7

Se si sta solo controllando prima di tentare di aggiungere un nuovo valore, utilizzare il metodo ContainsKey:

if (!openWith.ContainsKey("ht")) 
{ 
    openWith.Add("ht", "hypertrm.exe"); 
} 

Se stai controllando che il valore esiste, utilizzare il metodo TryGetValue come descritto nella risposta di Jon Skeet .

+5

TryGet è meglio –

+2

Coz si sta risolvendo la ricerca della chiave attraverso la tabella hash due volte se si ottiene immediatamente dopo l'Contiene. Wintellect PowerCollections ha anche i metodi 'GetValueElseAdd' che danno un valore (o un' Func ') per salvare anche la risoluzione sull'Insert se vuoi aggiungere se non c'è. Immagino che il motivo per cui non è entrato nelle librerie .NET è perché il percorso Aggiungi è meno frequente se lo si utilizza in uno stile cache] –

+0

@rub: Credo che ciò dipenda dallo scopo del codice. Se si desidera utilizzare il valore, concordo sul fatto che 'TryGetValue' sarebbe meglio, ma se si desidera verificare se il dizionario contiene la chiave per evitare aggiunte duplicate, direi che' ContainsKey' è altrettanto buono (se non migliore). –

2

Controllare la voce Dictionary.ContainsKey (chiave int) prima di provare a estrarre il valore.

Dictionary<int, int> myDictionary = new Dictionary<int, int>(); 
myDictionary.Add(2,4); 
myDictionary.Add(3,5); 

int keyToFind = 7; 
if(myDictionary.ContainsKey(keyToFind)) 
{ 
    myValueLookup = myDictionay[keyToFind]; 
    // do work... 
} 
else 
{ 
    // the key doesn't exist. 
} 
+2

Perché vuoi farlo fare la ricerca due volte? –

+1

@Jon perché di solito si legge meglio – mookid8000

+2

@mookid: Non è a mio avviso. L'idea è di cercare la chiave e prendere una linea di condotta se viene trovata, e un'altra linea di condotta altrimenti, giusto? –

0

Probabilmente si dovrebbe usare:

if(myDictionary.ContainsKey(someInt)) 
{ 
    // do something 
} 

Il motivo per cui non è possibile verificare la presenza di nulla è che la chiave qui è un tipo di valore.

+1

Il tipo del valore è in qualche modo irrilevante, poiché il controllo di null non avrebbe l'effetto desiderato. –

+0

@Johannes, la soluzione di Jon è ovviamente molto meglio, ma il richiedente ha affermato che ha controllato se la chiave esiste, ed è un dizionario , quindi la chiave è anche un tipo di valore qui. – Razzie

18

Dictionary genera un'eccezione KeyNotFound nel caso in cui il dizionario non contiene la chiave.

Come suggerito, ContainsKey è la precauzione appropriata. TryGetValue è anche efficace.

Ciò consente al dizionario di memorizzare un valore di null in modo più efficace. Senza il suo comportamento in questo modo, il controllo di un risultato nullo dall'operatore [] indicherebbe o un valore nullo OPPURE la non esistenza della chiave di input che non va bene.

+0

Ulteriori informazioni sono disponibili all'indirizzo MSDN: http://msdn.microsoft.com/en-gb/library/9tee9ht2.aspx – cyberzed

-1

una classe di supporto è a portata di mano:

public static class DictionaryHelper 
{ 
    public static TVal Get<TKey, TVal>(this Dictionary<TKey, TVal> dictionary, TKey key, TVal defaultVal = default(TVal)) 
    { 
     TVal val; 
     if(dictionary.TryGetValue(key, out val)) 
     { 
      return val; 
     } 
     return defaultVal; 
    } 
} 
Problemi correlati