2008-10-31 7 views
15

Derzeit verwende ichC# Wörterbücher ValueOrNull/ValueorDefault

var x = dict.ContainsKey(key) ? dict[key] : defaultValue 

ich irgendwie möchte Wörterbuch [key] haben für nonexistant Schlüssel null zurück, so konnte ich etwas schreiben wie

var x = dict[key] ?? defaultValue; 

das wird auch Teil von Linq-Abfragen usw., also würde ich Ein-Zeilen-Lösungen bevorzugen.

+0

Die aktuellen Antworten sind korrekt, und siehe auch [meine ähnliche Frage] (http://stackoverflow.com/questions/6214975), die eher eine Diskussion ist. Allerdings sollten Sie 'dict.ContainsKey (key) vermeiden? dict [key] ', wenn Sie zweimal nach dem Wörterbuch suchen, einmal nach dem' ContainsKey' und erneut nach dem '[]' Indexer. 'TryGetValue' ist hässlich und nicht inline, aber es ist eine einzelne Operation. – Keith

Antwort

21

Mit einer Erweiterungsmethode:

public static class MyHelper 
{ 
    public static V GetValueOrDefault<K, V>(this IDictionary<K, V> dic, 
              K key, 
              V defaultVal = default(V)) 
    { 
     V ret; 
     bool found = dic.TryGetValue(key, out ret); 
     if (found) { return ret; } 
     return defaultVal; 
    } 
    void Example() 
    { 
     var dict = new Dictionary<int, string>(); 
     dict.GetValueOrDefault(42, "default"); 
    } 
} 
+4

I zurückgeben würde eine Überladung anbieten, die den Standardwert (V) zurückgibt. – Will

+4

In C# 4 können Sie jetzt den Standardparameter optional machen: V defaultVal = default (V). Dann müssen Sie keinen Standard übergeben, wenn Sie nicht möchten - wenn der Wert nicht gefunden wird, erhalten Sie den Standard für den Typ V. – Tevin

+0

@Tevin können Sie einen Link zu msdn/article bereitstellen das dokumentiert dieses Verhalten? Ich bin mit .NET 4 nicht vertraut, aber der Standardoperator für einen Referenztyp in .NET 3.5 gibt null zurück und der Standardwert für einen Werttyp gibt den Wert mithilfe des Konstruktors ohne Argumente zurück. Ich bezweifle, dass sich das geändert hat? – toong

6

Sie können eine Hilfsmethode verwenden:

public abstract class MyHelper { 
    public static V GetValueOrDefault<K,V>(Dictionary<K,V> dic, K key) { 
     V ret; 
     bool found = dic.TryGetValue(key, out ret); 
     if (found) { return ret; } 
     return default(V); 
    } 
} 

var x = MyHelper.GetValueOrDefault(dic, key); 
+0

Sie können auch trivial, dass eine Erweiterung Methode, so dass Sie dict.GetValueOrDefault (Schlüssel) – stevemegson

+0

Ich dachte, dass er das in erster Linie ... Odd, dass der einzige Unterschied wäre das "dieses" Schlüsselwort. – Will

+3

Sie können dies auch unbedingt machen - geben Sie ret einfach nach dem Aufruf von TryGetValue zurück. Es wird Standard (V), wenn die Methode false zurückgibt. –

0

Sind das nicht einfach TryGetValue(key, out value), was Sie suchen? Zitiert von MSDN:

When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized. 

von http://msdn.microsoft.com/en-us/library/bb347013(v=vs.90).aspx

+0

Ich suchte nach einem einzeiligen Ausdruck. Das Problem mit 'TryGetValue' ist, dass 1) es eine Aussage ist. 2) es erfordert eine vorhergehende Deklaration der 'out'-Variablen. – Jimmy

4

Hier ist die „ultimative“ Lösung, da sie als eine Erweiterung Methode implementiert wird, verwendet die IDictionary-Schnittstelle bietet einen optionalen Standardwert und ist kompakt geschrieben.

public static TV GetValueOrDefault<TK, TV>(this IDictionary<TK, TV> dic, TK key, 
    TV defaultVal=default(TV)) 
{ 
    TV val; 
    return dic.TryGetValue(key, out val) 
     ? val 
     : defaultVal; 
}