2010-01-26 5 views

Antwort

138

Angenommen, Sie den Wert erhalten möchten, wenn der Schlüssel tut vorhanden ist, verwenden 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 
} 

(Mit ContainsKey und dann die der Indexer macht es den Schlüssel nachschlagen zweimal, das ist ziemlich sinnlos.

) Hinweis

dass selbst wenn Sie waren Referenztypen verwendet wird, würde für null Überprüfung nicht funktionieren - der Indexer für Dictionary<,> eine Exception aus, wenn Sie einen fehlenden Schlüssel anfordern, anstatt null zurück. (Dies ist ein großer Unterschied zwischen Dictionary<,> und Hashtable.)

+0

@JonSkeet Ist nicht TryGetValue auch eine doppelte Suche ([wie in dieser Frage body] (http://stackoverflow.com/questions/1413304/net-adding-dictionary-item-check-if-it-exists-) oder-Zulassen-Ausnahme))? – nawfal

+2

@ Nawfal: Ich sehe keinen Hinweis darauf, dass diese Frage überhaupt besagt. Es sagt, es macht mehr Arbeit als 'ContainsKey', was wahr ist, weil es auch den Wert extrahieren muss. Es tut aber nicht zwei Lookups. –

+0

Naiv, ich habe immer Null erwartet, aber für das Dictionary gibt dies das "0" -Äquivalent in der Enum zurück. – Jess

7

Wenn Sie überprüfen gerade, bevor Sie einen neuen Wert, verwenden Sie die ContainsKey Methode hinzufügen:

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

Wenn Sie prüfen, ob der Wert vorhanden ist, verwenden Sie die TryGetValue Methode wie in Jon Skeet Antwort beschrieben .

+5

TryGet besser ist –

+2

Coz Sie die Lösung der Schlüsselsuche durch die Hash-Tabelle zweimal, wenn Sie erhalten sofort nach dem Inhalt. Wintellect PowerCollections hat auch 'GetValueElseAdd' Methoden, denen Sie einen Wert (oder einen' Func '') geben, um die Auflösung auch im Insert zu speichern, wenn Sie hinzufügen wollen, wenn es nicht dort ist. Ich denke, der Grund, warum es nicht in die .NET-Bibliotheken geschafft wurde, ist, dass der Pfad zum Hinzufügen weniger häufig ist, wenn Sie ihn in einem Cache-Stil verwenden. –

+0

@rub: Ich denke, das hängt vom Zweck des Codes ab. Wenn Sie den Wert verwenden möchten, stimme ich zu, dass 'TryGetValue' besser wäre, aber wenn Sie überprüfen möchten, ob das Wörterbuch den Schlüssel enthält, um doppelte Ergänzungen zu vermeiden, würde ich sagen,' ContainsKey' ist genauso gut (wenn nicht besser). –

2

Sie sollten nach Dictionary.ContainsKey (Int-Taste) suchen, bevor Sie versuchen, den Wert herauszuziehen.

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

Warum willst du es zweimal machen? –

+1

@Jon weil es normalerweise besser liest – mookid8000

+2

@mookid: Nicht meiner Meinung nach. Die Idee ist, zu versuchen, den Schlüssel nachzuschlagen, und einen Kurs von Handlung zu machen, wenn es gefunden wird, und eine andere Vorgehensweise andernfalls, richtig? –

0

Sie sollten wahrscheinlich verwenden:

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

Der Grund, warum Sie nicht für null überprüfen kann, ist, dass der Schlüssel hier ein Werttyp ist.

+1

Der Typ des Wertes ist irrelevant, da die Überprüfung auf Null nicht den gewünschten Effekt haben würde. –

+0

@Johannes, Jon's Lösung ist natürlich viel besser, aber der Fragesteller hat festgestellt, dass er überprüft hat, ob der Schlüssel existiert, und es ist ein Dictionary , also ist der Schlüssel auch ein Werttyp hier. – Razzie

18

Das Wörterbuch löst eine KeyNotFound Ausnahme aus, falls das Wörterbuch Ihren Schlüssel nicht enthält.

Wie vorgeschlagen, ContainsKey ist die entsprechende Vorsichtsmaßnahme. TryGetValue ist auch effektiv.

Dies ermöglicht dem Wörterbuch, einen Wert von Null effektiver zu speichern. Ohne dieses Verhalten würde das Prüfen auf ein Null-Ergebnis des Operators [] entweder einen Nullwert ODER die Nicht-Existenz des Eingabeschlüssels anzeigen, was nicht gut ist.

+0

Weitere Informationen finden Sie unter MSDN: http://msdn.microsoft.com/en-gb/library/9tee9ht2.aspx – cyberzed

-1

Eine Hilfsklasse ist praktisch:

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; 
    } 
} 
Verwandte Themen