StringDictionary vs Dictionary <string, string>

76

Hat jemand eine Idee, was die praktischen Unterschiede zwischen dem System.Collections.Specialized.StringDictionary-Objekt und System.Collections.Generic.Dictionary sind?

Ich habe sie beide in der Vergangenheit verwendet, ohne viel darüber nachzudenken, welche besser funktionieren, besser mit Linq zusammenarbeiten oder andere Vorteile bieten würden.

Irgendwelche Gedanken oder Vorschläge, warum ich einen über den anderen verwenden sollte?

Scott Ivey
quelle

Antworten:

90

Dictionary<string, string>ist ein moderner Ansatz. Es implementiert IEnumerable<T>und ist besser für LINQy-Inhalte geeignet.

StringDictionaryist der Weg der alten Schule. Es war dort vor Generika-Tagen. Ich würde es nur verwenden, wenn ich mit Legacy-Code zusammenarbeite.

Mehrdad Afshari
quelle
Sie sollten einen Benchmark durchführen, um festzustellen, welche für Ihre spezielle Situation besser geeignet ist. Ich erwarte keinen spürbaren Leistungsunterschied. Ich empfehle die Verwendung Dictionary<string,string>für den gesamten neuen Code (es sei denn, Sie müssen auf 1.1 abzielen).
Mehrdad Afshari
2
@thecoop keine harten Daten von meiner Seite jetzt zu präsentieren, aber einmal, als ich auf Geschwindigkeit getestet habe, StringDictionaryschlechter abgeschnitten (obwohl all das meistens nicht wichtig ist). Um ehrlich zu sein, hatte ich früher die Vorstellung, dass StringDictionaryes sich um eine spezialisierte Sammlung handelt, die dazu gedacht ist, die Dinge zu beschleunigen, wenn dies stringder Schlüssel war, und zu meiner großen Überraschung, als sie bei meinen Tests schlechter abschnitt, habe ich sie nur gegoogelt, um zu erfahren, dass sie nicht generisch ist
Nawfal
1
@nawfal Ich denke, es ist langsamer, weil StringDictionary standardmäßig die Groß- und Kleinschreibung nicht berücksichtigt. Wenn Sie ein Wörterbuch mit einem Schlüsselvergleicher erstellen, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird, ist die Leistung
meines Erachtens
41

Ein weiterer Punkt.

Dies gibt null zurück:

StringDictionary dic = new StringDictionary();
return dic["Hey"];

Dies löst eine Ausnahme aus:

Dictionary<string, string> dic = new Dictionary<string, string>();
return dic["Hey"];
Joshcomley
quelle
Die „löst eine Ausnahme“ Merkmal der Dictionary<>Mittel i nie verwenden können []. Use StringDictionary hat einen Großteil meines Codes bereinigt.
James Curran
1
@ James Ich bin etwas spät dran, aber du solltest wahrscheinlich TryGetValue verwenden.
Şafak Gür
@ ŞafakGür - ich Sie verwenden TryGetValue () - weil ich nie verwenden können , [ ]weil es eine Ausnahme auslöst. (StringDictionary löst dies nur für eine Art von Wörterbüchern)
James Curran
@James, ich glaube, das Auslösen einer Ausnahme für nicht vorhandene Schlüssel ist eine bessere API-Wahl, da null als Wörterbuchwert zulässig ist. Auf diese Weise können Sie zwischen einem nicht vorhandenen Schlüssel und einem Schlüssel mit dem Wert null unterscheiden.
Şafak Gür
1
@ ŞafakGür das ist wahr - wenn Sie ein Wörterbuch benötigen, das a) immer alle Werte haben sollte, b) Nullen enthalten kann und c) diese Null etwas anderes bedeutet als "kein Wert". In einem Wörterbuch jedoch "nein value "wird normalerweise durch den Schlüssel dargestellt, der nicht vorhanden ist. Der wahre Grund, warum Dictionary <> eine Ausnahme auslöst, ist, dass der Wert ein Werttyp sein kann (und daher nicht mit einer Null dargestellt werden kann).
James Curran
36

Ich denke, StringDictionary ist ziemlich veraltet. Es existierte in Version 1.1 des Frameworks (vor Generika), daher war es zu dieser Zeit eine überlegene Version (im Vergleich zum nicht generischen Wörterbuch), aber an diesem Punkt glaube ich nicht, dass es irgendwelche spezifischen Vorteile gibt über Wörterbuch.

StringDictionary hat jedoch Nachteile. StringDictionary schreibt Ihre Schlüsselwerte automatisch in Kleinbuchstaben, und es gibt keine Optionen, um dies zu steuern.

Sehen:

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/59f38f98-6e53-431c-a6df-b2502c60e1e9/

Reed Copsey
quelle
2
StringDictionarykann verwendet werden, Properites.Settingssolange Dictionary<string,string>nicht. So veraltet oder nicht, es gibt immer noch eine Verwendung für StringDictionary.
Jahu
36

Wie Reed Copsey betonte, schreibt StringDictionary Ihre Schlüsselwerte in Kleinbuchstaben. Für mich war das völlig unerwartet und ist ein Show-Stopper.

private void testStringDictionary()
{
    try
    {
        StringDictionary sd = new StringDictionary();
        sd.Add("Bob", "My name is Bob");
        sd.Add("joe", "My name is joe");
        sd.Add("bob", "My name is bob"); // << throws an exception because
                                         //    "bob" is already a key!
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

Ich füge diese Antwort hinzu, um mehr Aufmerksamkeit auf diesen großen Unterschied zu lenken , der IMO wichtiger ist als der Unterschied zwischen moderner und alter Schule.

Jeff Roe
quelle
4
Wenn aus irgendeinem Grund dasselbe Verhalten mit Dictionary <string, string> gewünscht wird, kann dies verwendet werden: Dictionary <string, string> ht = new Dictionary <string, string> (StringComparer.OrdinalIgnoreCase); ht.Add ("Bob", "ff"); ht.Add ("bob", "ff"); //
löst eine
2

StringDictionary kommt aus .NET 1.1 und implementiert IEnumerable

Dictionary<string, string> kommt aus .NET 2.0 und implementiert IDictionary<TKey, TValue>,IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable

IgnoreCase ist nur für Key in eingestellt StringDictionary

Dictionary<string, string> ist gut für LINQ

        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        dictionary.Add("ITEM-1", "VALUE-1");
        var item1 = dictionary["item-1"];       // throws KeyNotFoundException
        var itemEmpty = dictionary["item-9"];   // throws KeyNotFoundException

        StringDictionary stringDictionary = new StringDictionary();
        stringDictionary.Add("ITEM-1", "VALUE-1");
        var item1String = stringDictionary["item-1"];     //return "VALUE-1"
        var itemEmptystring = stringDictionary["item-9"]; //return null

        bool isKey = stringDictionary.ContainsValue("VALUE-1"); //return true
        bool isValue = stringDictionary.ContainsValue("value-1"); //return false
ArekBee
quelle
1

Abgesehen davon, dass es sich um eine "modernere" Klasse handelt, habe ich festgestellt, dass Dictionary mit großem Abstand speichereffizienter als StringDictionary ist.

Daniel
quelle
11
Wir könnten hier einige Zahlen verwenden
Zonko
1

Ein weiterer relevanter Punkt ist, dass (korrigieren Sie mich, wenn ich mich hier irre) System.Collections.Generic.Dictionarynicht in den Anwendungseinstellungen ( Properties.Settings) verwendet werden kann, wohingegen dies der Fall System.Collections.Specialized.StringDictionaryist.

Matt Lyons
quelle