Der Indexer in Dictionary löst eine Ausnahme aus, wenn der Schlüssel fehlt. Gibt es eine Implementierung von IDictionary, die stattdessen den Standardwert (T) zurückgibt?
Ich kenne die "TryGetValue" -Methode, aber das ist mit linq unmöglich zu verwenden.
Würde dies effizient das tun, was ich brauche?:
myDict.FirstOrDefault(a => a.Key == someKeyKalue);
Ich denke nicht, dass es so sein wird, wie ich denke, dass es die Schlüssel iterieren wird, anstatt eine Hash-Suche zu verwenden.
c#
.net
hash
dictionary
TheSoftwareJedi
quelle
quelle
Antworten:
In der Tat wird das überhaupt nicht effizient sein.
Sie können jederzeit eine Erweiterungsmethode schreiben:
Oder mit C # 7.1:
Das verwendet:
quelle
return (dictionary.ContainsKey(key)) ? dictionary[key] : default(TValue);
System.Collections.Generic.CollectionExtensions
, da ich es gerade versucht habe und es da ist.Das Tragen dieser Erweiterungsmethoden kann helfen.
quelle
Func<K, V>
.Wenn jemand .net Core 2 und höher (C # 7.X) verwendet, wird die CollectionExtensions- Klasse eingeführt und kann die GetValueOrDefault- Methode verwenden, um den Standardwert abzurufen , wenn der Schlüssel nicht in einem Wörterbuch vorhanden ist.
quelle
Collections.Specialized.StringDictionary
liefert ein Ergebnis ohne Ausnahme, wenn der Wert eines fehlenden Schlüssels nachgeschlagen wird. Standardmäßig wird auch die Groß- und Kleinschreibung nicht berücksichtigt.Vorsichtsmaßnahmen
Es ist nur für spezielle Zwecke gültig und verfügt - da es vor Generika entwickelt wurde - nicht über einen sehr guten Enumerator, wenn Sie die gesamte Sammlung überprüfen müssen.
quelle
Wenn Sie .Net Core verwenden, können Sie die CollectionExtensions.GetValueOrDefault- Methode verwenden. Dies entspricht der Implementierung in der akzeptierten Antwort.
quelle
quelle
Man könnte eine Schnittstelle für die Schlüsselsuchfunktion eines Wörterbuchs definieren. Ich würde es wahrscheinlich so definieren wie:
Die Version mit nicht generischen Schlüsseln würde Code zulassen, der Code mit nicht strukturierten Schlüsseltypen verwendet, um eine beliebige Schlüsselvarianz zu ermöglichen, die mit einem generischen Typparameter nicht möglich wäre. Man sollte nicht erlaubt sein, eine veränderbare
Dictionary(Of Cat, String)
als veränderbare zu verwenden,Dictionary(Of Animal, String)
da letztere dies erlauben würdeSomeDictionaryOfCat.Add(FionaTheFish, "Fiona")
. Aber es ist nichts Falsches daran, eine veränderbareDictionary(Of Cat, String)
als unveränderlich zu verwendenDictionary(Of Animal, String)
, daSomeDictionaryOfCat.Contains(FionaTheFish)
sie als perfekt geformter Ausdruck betrachtet werden sollte (sie solltefalse
, ohne das Wörterbuch durchsuchen zu müssen, nach etwas zurückkehren, das nicht vom Typ istCat
).Leider kann man eine solche Schnittstelle nur dann tatsächlich verwenden, wenn man ein
Dictionary
Objekt in eine Klasse einschließt, die die Schnittstelle implementiert. Je nachdem, was Sie tun, ist eine solche Schnittstelle und die zulässige Varianz möglicherweise die Mühe wert.quelle
Wenn Sie ASP.NET MVC verwenden, können Sie die RouteValueDictionary-Klasse nutzen, die den Job ausführt.
quelle
Diese Frage half zu bestätigen, dass das
TryGetValue
spieltFirstOrDefault
hier Rolle .Eine interessante C # 7-Funktion, die ich erwähnen möchte, ist die Out-Variablen- Funktion. Wenn Sie der Gleichung den nullbedingten Operator von C # 6 hinzufügen, könnte Ihr Code viel einfacher sein, ohne dass zusätzliche Erweiterungsmethoden erforderlich sind.
Der Nachteil dabei ist, dass Sie nicht alles so inline machen können.
Wenn wir dies brauchen / wollen, sollten wir eine Erweiterungsmethode wie die von Jon codieren.
quelle
Hier ist eine Version von @ JonSkeet für die Welt von C # 7.1, mit der auch ein optionaler Standard übergeben werden kann:
Es kann effizienter sein, zwei Funktionen zu haben, um den Fall zu optimieren, in dem Sie zurückkehren möchten
default(TV)
:Leider hat C # (noch?) Keinen Kommaoperator (oder den von C # 6 vorgeschlagenen Semikolonoperator), so dass Sie für eine der Überladungen einen tatsächlichen Funktionskörper (keuchen!) Haben müssen.
quelle
Ich habe die Kapselung verwendet, um ein IDictionary mit einem Verhalten zu erstellen, das einer STL-Map sehr ähnlich ist , für diejenigen unter Ihnen, die mit C ++ vertraut sind. Für diejenigen, die nicht sind:
TL / DR - SafeDictionary wurde so geschrieben, dass unter keinen Umständen Ausnahmen außer in perversen Szenarien ausgelöst werden , z. B. wenn der Computer nicht Speicher hat (oder in Flammen steht). Dazu wird Add durch AddOrUpdate-Verhalten ersetzt und der Standardwert zurückgegeben, anstatt NotFoundException aus dem Indexer auszulösen.
Hier ist der Code:
quelle
Seit .NET Core 2.0 können Sie Folgendes verwenden:
quelle
Was ist mit diesem
ContainsKey
Einzeiler , der prüft, ob ein Schlüssel vorhanden ist, und dann entweder den normalerweise erhaltenen Wert oder den Standardwert mit dem bedingten Operator zurückgibt?Sie müssen keine neue Dictionary-Klasse implementieren, die Standardwerte unterstützt. Ersetzen Sie einfach Ihre Lookup-Anweisungen durch die kurze Zeile oben.
quelle
Es könnte ein Einzeiler sein, um den
TryGetValue
Standardwert zu überprüfen und zurückzugeben, wenn dies der Fall istfalse
.myKey = "One"
=>value = 1
myKey = "two"
=>value = 100
myKey = "Four"
=>value = 4
Probieren Sie es online aus
quelle
Nein, denn wie würden Sie sonst den Unterschied erkennen, wenn der Schlüssel vorhanden ist, aber einen Nullwert gespeichert hat? Das könnte von Bedeutung sein.
quelle