Frage Kann jemand erklären, warum Dictionary <> in C # nicht funktioniert wie map in STL?


Als ich letztes Jahr anfing, in C # zu programmieren, suchte ich sofort nach dem Äquivalent zur STL-Karte und lernte etwas über das Wörterbuch.

AKTUALISIEREN Ich habe diesen Müll unterstrichen, ich lag völlig falsch. Meine Erfahrung mit der STL-Karte war, dass ich es hasste, wenn ich nach einem Wert fragte, und wenn der Schlüssel nicht in der Karte enthalten war, würde er automatisch den Werttyp (was auch immer sein Standardkonstruktor tat) erstellen und zur Karte hinzufügen. Ich müsste dann im Code nach dieser Bedingung suchen und eine Ausnahme auslösen.

Dictionary <> ruft den gesamten Shebang korrekt ab - wenn der Schlüssel nicht vorhanden ist, löst er die Exception aus, wenn Sie den Wert anfordern, oder fügt sie automatisch hinzu, wenn dies nicht der Fall ist und Sie den Wert festlegen möchten.

Aber das wussten Sie alle schon. Ich hätte meine Unit-Tests schreiben sollen, bevor ich hier poste und mich selbst in Verlegenheit bringe. :) Sie sind jetzt geschrieben!

Jetzt liebe ich Wörterbuch und alle, aber die Sache, die mich am meisten darüber ärgert jetzt sofort Wenn der Schlüssel nicht im Dictionary ist, wird eine KeyNotFoundException ausgelöst. Daher muss ich Code immer so schreiben:

Dictionary<string,string> _mydic;

public string this[string key]
{
  get {
    return _mydic[key]; // could throw KeyNotFoundException
  }
  set {
    if( _mydic.ContainsKey( key))
      _mydic[key] = value;
    else
      _mydic.Add( key, value);
  }
}

Warum fügt das Wörterbuch das Schlüsselwertpaar nicht automatisch hinzu, wenn der Schlüssel nicht existiert, wie die STL-Karte?

Jetzt ist das Lustige daran, dass ich in einem früheren Leben genervt war, weil ich es oft versuchen musste verhindern Karte davon, genau das zu tun. Ich denke, meine Anwendungsfälle sind jetzt ein wenig anders.


5
2018-03-05 17:55


Ursprung


Antworten:


Welchen Wert möchten Sie zurückgeben, wenn er nicht bereits in der Karte vorhanden ist? Es könnte Rückkehr default(TValue) - Aber dann wäre es etwas einfach, versehentlich einen Wert zu verwenden, vorausgesetzt, es war korrekt. Wenn Sie dieses Verhalten wünschen, können Sie Folgendes verwenden:

get {
  string value;
  if (!_mydic.TryGetValue(key, out value))
    value = default(string);
  return value;
}

Ich würde es im Allgemeinen nicht persönlich empfehlen, aber wenn Sie froh sind, nicht (über diesen Indexer) zwischen einem Schlüssel mit einem Nullwert und einem fehlenden Schlüssel unterscheiden zu können, wird es den Trick machen.

Beachten Sie, dass Ihr Setter mir viel einfacher - nur

_mydic[key] = value;

Wird bei Bedarf überschrieben.


10
2018-03-05 18:00



Ich stimme der Behandlung der Ausnahme zu, ist irgendwie ärgerlich, besonders für Referenztypen, wenn es sinnvoll ist, eine Null zu bekommen. In jedem Fall können Sie jedoch verwenden Dictionary<>.TryGetValue() um den Wert in einem Anruf zu erhalten.


3
2018-03-05 18:04



Ich bin verwirrt. Es tut, hier. Das Dokumente sage sogar so:

When you set the property value, if the key is in the Dictionary(TKey, TValue), the value associated with that key is replaced by the assigned value. If the key is not in the Dictionary(TKey, TValue), the key and value are added to the dictionary.

und

KeyNotFoundException: The property is retrieved and key does not exist in the collection.

(keine Erwähnung, dass es während des Einsatzes geworfen wird).


0
2018-03-05 18:17