153 Stimmen

Verschiedene Möglichkeiten, dem Wörterbuch etwas hinzuzufügen

Worin besteht der Unterschied zwischen Dictionary.add(key, value) y Dictionary[key] = value ?

Ich habe bemerkt, dass die letzte Version keine Fehlermeldung ArgumentException beim Einfügen eines doppelten Schlüssels, aber gibt es einen Grund, die erste Version vorzuziehen?

bearbeiten : Hat jemand eine verlässliche Quelle für Informationen zu diesem Thema? Ich habe es bei MSDN versucht, aber es ist wie immer eine aussichtslose Suche :(

151voto

Steffen Punkte 13138

Die Leistung ist fast zu 100 % identisch. Sie können dies überprüfen, indem Sie die Klasse in Reflector.net öffnen

Dies ist der Indexer:

public TValue this[TKey key]
{
    get
    {
        int index = this.FindEntry(key);
        if (index >= 0)
        {
            return this.entries[index].value;
        }
        ThrowHelper.ThrowKeyNotFoundException();
        return default(TValue);
    }
    set
    {
        this.Insert(key, value, false);
    }
}

Und das ist die Add-Methode:

public void Add(TKey key, TValue value)
{
    this.Insert(key, value, true);
}

Ich werde nicht die gesamte Insert-Methode posten, da sie ziemlich lang ist, aber die Methodendeklaration ist die folgende:

private void Insert(TKey key, TValue value, bool add)

Und weiter unten in der Funktion geschieht dies:

if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key))
{
    if (add)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
    }

Es wird geprüft, ob der Schlüssel bereits existiert, und wenn dies der Fall ist und der Parameter add true ist, wird die Ausnahme ausgelöst.

Die Leistung ist also in jeder Hinsicht dieselbe.

Wie bereits erwähnt, kommt es darauf an, ob Sie die Prüfung benötigen, wenn Sie versuchen, denselben Schlüssel zweimal hinzuzufügen.

Entschuldigung für den langen Beitrag, ich hoffe, das ist in Ordnung.

1 Stimmen

+1 Sehr interessant, danke für Ihren Beitrag! Es scheint, dass die Leistung hier fast identisch ist, wie die anderen Poster angedeutet haben, trotzdem toller Fund :)

0 Stimmen

Ob absichtlich oder nicht, ich finde es gut, dass Sie die Reihenfolge der Absichten/Zwecke vertauscht haben und damit jedes falsche Verständnis von "intensiven" Absichten bei den Lesern ausräumen.

93voto

hhravn Punkte 1631

Die erste Version fügt dem Wörterbuch ein neues KeyValuePair hinzu und wirft, wenn key bereits im Wörterbuch enthalten ist. Die zweite Version, die den Indexer verwendet, fügt ein neues Paar hinzu, wenn der Schlüssel nicht vorhanden ist, überschreibt aber den Wert des Schlüssels, wenn er bereits im Wörterbuch vorhanden ist.

IDictionary<string, string> strings = new Dictionary<string, string>();

strings["foo"] = "bar";          //strings["foo"] == "bar"
strings["foo"] = string.Empty;   //strings["foo"] == string.empty
strings.Add("foo", "bar");       //throws

0 Stimmen

+1 Haben Sie eine Quelle für die oben genannten Informationen? Ich bin daran interessiert zu erfahren, ob es irgendwelche Nebenwirkungen oder Vorbehalte bei der Verwendung der ersten oder zweiten Form gibt.

3 Stimmen

Ich habe nicht wirklich eine Quelle als solche, nur aus dem Stegreif, aber ich glaube nicht, dass da viel mehr dran ist, als in den anderen Kommentaren erwähnt. Wenn ich mich richtig erinnere, verwendet Add einfach den Indexer, prüft aber zuerst, ob der Schlüssel bereits in Gebrauch ist.

1 Stimmen

Die akzeptierte Antwort wurde in die von Steffen geändert, da seine Dokumentation erstklassig ist. Dies ist aber immer noch eine großartige Antwort.

62voto

nethero Punkte 576

Um diese Frage zu beantworten, müssen wir zunächst einen Blick auf den Zweck eines Wörterbuchs und die zugrunde liegende Technologie werfen.

Dictionary ist die Liste der KeyValuePair<Tkey, Tvalue> wobei jeder Wert durch seinen eindeutigen Schlüssel dargestellt wird. Nehmen wir an, wir haben eine Liste Ihrer Lieblingsspeisen. Jeder Wert (Name des Lebensmittels) wird durch seinen eindeutigen Schlüssel dargestellt (eine Position = wie sehr Sie dieses Lebensmittel mögen).

Beispiel-Code:

Dictionary<int, string> myDietFavorites = new Dictionary<int, string>()
{
    { 1, "Burger"},
    { 2, "Fries"},
    { 3, "Donuts"}
};

Angenommen, Sie wollen gesund bleiben, haben Ihre Meinung geändert und wollen Ihren Lieblings-Burger durch Salat ersetzen. Ihre Liste ist immer noch eine Liste mit Ihren Lieblingsgerichten, Sie werden die Art der Liste nicht ändern. Ihr Lieblingsessen bleibt die Nummer eins auf der Liste, nur sein Wert ändert sich. Dies ist der Moment, in dem Sie dies aufrufen:

/*your key stays 1, you only replace the value assigned to this key
  you alter existing record in your dictionary*/
myDietFavorites[1] = "Salad";

Aber vergiss nicht, dass du der Programmierer bist, und von nun an beendest du deine Sätze mit ; du weigerst dich, Emojis zu verwenden, weil sie einen Kompilierungsfehler verursachen würden, und alle Favoritenlisten basieren auf dem Index 0.

Auch Ihre Ernährung hat sich geändert! Also ändern Sie Ihre Liste erneut:

/*you don't want to replace Salad, you want to add this new fancy 0
  position to your list. It wasn't there before so you can either define it*/
myDietFavorites[0] = "Pizza";

/*or Add it*/
myDietFavorites.Add(0, "Pizza");

Beim Definieren gibt es zwei Möglichkeiten: Entweder man will eine neue Definition für etwas geben, das es vorher nicht gab, oder man will eine bereits vorhandene Definition ändern.

Mit der Add-Methode können Sie einen Datensatz hinzufügen, allerdings nur unter einer Bedingung: Der Schlüssel für diese Definition darf nicht in Ihrem Wörterbuch vorhanden sein.

Jetzt werden wir unter die Haube schauen. Wenn Sie ein Wörterbuch erstellen, reserviert Ihr Compiler einen Bucket (Speicherplatz zum Speichern der Datensätze). Buckets speichern die Schlüssel nicht so, wie Sie sie definieren. Jeder Schlüssel wird gehasht, bevor er im Bucket gespeichert wird (von Microsoft definiert), wobei der Wert unverändert bleibt.

Zur Vereinfachung meines Beispiels verwende ich den CRC32-Hash-Algorithmus. Wenn Sie definieren:

myDietFavorites[0] = "Pizza";

Was in den Eimer kommt, ist db2dc565 "Pizza" (vereinfacht).

Wenn Sie den Wert in mit ändern:

myDietFavorites[0] = "Spaghetti";

Sie hacken Ihre 0, die wiederum db2dc565 dann suchen Sie diesen Wert in Ihrem Eimer, um herauszufinden, ob er dort vorhanden ist. Wenn er vorhanden ist, schreiben Sie den dem Schlüssel zugewiesenen Wert einfach um. Wenn er nicht vorhanden ist, legen Sie Ihren Wert in den Bereich.

Wenn Sie die Funktion Hinzufügen für Ihr Wörterbuch aufrufen, z. B:

myDietFavorite.Add(0, "Chocolate");

Du hasst deine 0, um ihren Wert mit Einsen im Eimer zu vergleichen. Sie können sie in den Eimer legen nur wenn er nicht da ist .

Es ist wichtig zu wissen, wie es funktioniert, vor allem, wenn Sie mit Wörterbüchern von String- oder Char-Typ Schlüssel arbeiten. Die Groß- und Kleinschreibung wird beim Hashing unterschieden. Also zum Beispiel "Name" != "Name". Verwenden wir unseren CRC32, um dies darzustellen.

Der Wert für "Name" ist: e04112b1 Der Wert für "Name" ist: 1107fb5b

0 Stimmen

Diese zwei Zeilen reichen aus, um ....... zu verstehen. Beim Definieren gibt es zwei Möglichkeiten, entweder man will eine neue Definition für etwas geben, das es noch nicht gibt, oder man will eine bereits vorhandene Definition ändern. Mit der Add-Methode können Sie einen Datensatz hinzufügen, aber nur unter einer Bedingung: Der Schlüssel für diese Definition darf nicht in Ihrem Wörterbuch vorhanden sein.

2 Stimmen

Ich gehe davon aus, dass die Person, die diese Frage stellt, über ein gewisses Maß an Wissen oder Unwissenheit verfügt, daher die Übererläuterung.

39voto

Michael Damatov Punkte 14513

Dictionary.Add(key, value) y Dictionary[key] = value haben unterschiedliche Ziele:

  • Verwenden Sie die Add Methode zu hinzufügen. neues Schlüssel/Wert-Paar, vorhandene Schlüssel werden nicht ersetzt (ein ArgumentException geworfen wird).
  • Verwenden Sie den Indexer, wenn es Ihnen egal ist, ob der Schlüssel bereits im Wörterbuch vorhanden ist, mit anderen Worten: fügen Sie das Schlüssel/Wert-Paar hinzu, wenn der Schlüssel nicht im Wörterbuch enthalten ist, oder ersetzen Sie den Wert für den angegebenen Schlüssel, wenn der Schlüssel bereits im Wörterbuch enthalten ist.

2 Stimmen

Code, der seine Absicht selbst beschreibt, ist wichtig und ungemein wertvoll (und erfordert wenig bis keine Kommentare). Diese Antwort zeigt den Unterschied in der Absicht beider Methoden und sollte bei der Wahl einer Methode beachtet werden. Mit anderen Worten: Verwenden Sie nicht die Methode "indexer add", wenn Sie im Voraus wissen die Sie immer hinzufügen werden, oder sogar muss immer hinzufügen. Das Auslösen einer IndexOutOfBounds-Ausnahme ist besser als ein unerwartetes Verhalten.

5voto

Guffa Punkte 663241

Ja, das ist der Unterschied, die Add-Methode löst eine Ausnahme aus, wenn der Schlüssel bereits existiert.

Der Grund für die Verwendung der Add-Methode ist genau dieser. Wenn das Wörterbuch den Schlüssel nicht bereits enthalten soll, wollen Sie normalerweise eine Ausnahme, damit Sie auf das Problem aufmerksam gemacht werden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X