CodeGym /Kurse /C# SELF /Vertrag für Wörterbuch: ID...

Vertrag für Wörterbuch: IDictionary<TKey, TValue>

C# SELF
Level 28, Lektion 4
Verfügbar

1. Einführung

Stell dir vor: Du fängst in einem geheimen Labor für Katzenforschung an. Deine Aufgabe: Ein elektronisches Katzen-Wörterbuch bauen, wo du anhand des Namens schnell das Alter, die Farbe und die Schwanzlänge einer Katze herausfinden kannst. Die fertige Lösung gibt's schon – das ist Dictionary<string, Cat>. Aber dann sagt dein Chef plötzlich, dass für manche seltene Rassen das Wörterbuch die Einfügereihenfolge behalten soll, und manchmal soll es auch nach einer speziellen Logik gelöscht werden.

Was, wenn du eine Methode schreiben willst, die mit jedem „Katzen-Wörterbuch“ umgehen kann? Egal, welche Klasse genau – Hauptsache, sie unterstützt die wichtigsten „Key-Value“-Operationen. Genau hier kommt das Interface IDictionary<TKey, TValue> ins Spiel.

IDictionary<TKey, TValue> ist ein allgemeiner Vertrag, der definiert, was ein Wörterbuch in .NET ist. Das ist keine konkrete Klasse, sondern ein Interface, also ein Satz von Regeln, die jedes echte Wörterbuch unterstützen muss:

  • Schnelles Suchen nach Schlüssel
  • Hinzufügen und Entfernen von „Key-Value“-Paaren
  • Durchlaufen aller Paare
  • Prüfen, ob ein Schlüssel existiert

Wenn es Java im Mittelalter gegeben hätte, hätten seine Ritter statt Schwertern gegen Drachen mit Schlüsseln und Werten gekämpft. Und C#-Entwickler hätten einfach IDictionary<TKey, TValue> implementiert – und der Drache (also dein Code) wäre besiegt.

2. Tabelle des IDictionary-Interfaces

Schauen wir uns die wichtigsten „Versprechen“ (Mitglieder) dieses Interfaces an:

Interface-Mitglied Typ Beschreibung
this[TKey key]
Eigenschaft Indexer. Damit kannst du den Wert zu einem bestimmten Schlüssel bekommen oder setzen. Beim Lesen: Wenn der Schlüssel nicht gefunden wird, fliegt KeyNotFoundException. Beim Schreiben: Wenn der Schlüssel nicht existiert, wird ein neues Paar hinzugefügt; wenn der Schlüssel schon da ist, wird der Wert aktualisiert. Wichtig: Das ist der häufigste Weg, mit Wörterbüchern zu arbeiten.
ICollection<TKey> Keys
Eigenschaft Gibt eine Sammlung mit allen Schlüsseln im Wörterbuch zurück. Damit kannst du nur die Schlüssel durchlaufen.
ICollection<TValue> Values
Eigenschaft Gibt eine Sammlung mit allen Werten im Wörterbuch zurück. Damit kannst du nur die Werte durchlaufen.
Add(TKey key, TValue value)
Methode Fügt den angegebenen Schlüssel und Wert ins Wörterbuch ein. Wenn der Schlüssel schon existiert, gibt's ArgumentException.
ContainsKey(TKey key)
Methode Prüft, ob das Wörterbuch ein Element mit dem angegebenen Schlüssel enthält. Gibt true zurück, wenn der Schlüssel gefunden wurde; sonst false. Sehr praktisch, um Fehler zu vermeiden, wenn du mit dem Indexer auf einen nicht existierenden Schlüssel zugreifen willst.
Remove(TKey key)
Methode Entfernt das Element mit dem angegebenen Schlüssel aus dem Wörterbuch. Gibt true zurück, wenn das Element gefunden und entfernt wurde; sonst false (zum Beispiel, wenn der Schlüssel nicht gefunden wurde).
TryGetValue(TKey key, out TValue value)
Methode Holt den Wert, der mit dem angegebenen Schlüssel verknüpft ist. Das ist der sichere Weg, einen Wert zu bekommen, wenn du nicht sicher bist, ob der Schlüssel existiert. Gibt true zurück, wenn der Schlüssel gefunden wurde, und value enthält den Wert; sonst false und value bekommt den Standardwert für TValue. Diese Methode wirft keine Exception, was sie im echten Code sehr beliebt macht.

3. Die wichtigsten Mitglieder von IDictionary<TKey, TValue>

Jetzt zum Wichtigsten! Schauen wir uns an, was im Interface IDictionary<TKey, TValue> steckt und wie du diesen „Vertrag“ in deinem Code nutzt.


public interface IDictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>
{
    TValue this[TKey key] { get; set; } // Indexer für Zugriff per Schlüssel
    ICollection<TKey> Keys { get; }
    ICollection<TValue> Values { get; }
    void Add(TKey key, TValue value); // Neues Paar hinzufügen (Schlüssel darf nicht existieren) 
    bool ContainsKey(TKey key); // Gibt's diesen Schlüssel?
    bool Remove(TKey key); // Nach Schlüssel entfernen
    bool TryGetValue(TKey key, out TValue value); // Sicher Wert holen
}

Lass uns die wichtigsten Punkte anschauen:

Indexer [key]

Damit kannst du Werte per Schlüssel bekommen und setzen:

dictionary["Barsik"] = new Cat("Barsik", 2);

Eigenschaften Keys und Values

Damit bekommst du die Sammlung aller Schlüssel oder aller Werte im Wörterbuch.

foreach (var name in dictionary.Keys)
{
    Console.WriteLine(name);
}

Methoden Add, Remove, ContainsKey, TryGetValue

  • Add(key, value) – neues Paar hinzufügen
  • Remove(key) – nach Schlüssel entfernen
  • ContainsKey(key) – prüfen, ob Schlüssel existiert
  • TryGetValue(key, out value) – sicher Wert holen (ohne Exception, falls Schlüssel fehlt)

4. IDictionary<TKey, TValue> in der Praxis nutzen

Generische Methoden

Angenommen, du schreibst eine Funktion, die mit einem Wörterbuch arbeiten soll, aber nicht wissen will, welche Klasse dahintersteckt: ein normales Dictionary, ein SortedDictionary oder vielleicht hat jemand sein eigenes „Crypto-Kollektiv-Wörterbuch“ gebaut.

Du deklarierst den Parameter als IDictionary<TKey, TValue>:


static void PrintDictionary<TKey, TValue>(IDictionary<TKey, TValue> someDictionary)
{
    foreach (var pair in someDictionary)
    {
        Console.WriteLine($"{pair.Key}: {pair.Value}");
    }
}

Jetzt nimmt deine Methode jedes Wörterbuch! Unter der Haube kann alles stecken – sogar ein Wörterbuch, das Werte verschlüsselt, wenn du so viel Spaß im Leben hast.

IDictionary für Parameterübergabe nutzen

Angenommen, du baust eine App zur Katzenverwaltung und willst, dass deine Methode mit allen möglichen Wörterbüchern für Einstellungen umgehen kann, nicht nur mit einer bestimmten Klasse. So sieht das aus:


void SetCatParameters(IDictionary<string, string> parameters)
{
    if (parameters.ContainsKey("color"))
    {
        Console.WriteLine($"Färbe die Katze in Farbe: {parameters["color"]}");
    }
}

Eine Signatur – viele Implementierungen

Erklären wir das mal in einer Tabelle:

Sammlungsklasse Implementiert IDictionary<TKey,TValue> Besonderheiten
Dictionary<TKey, TValue>
✅ Ja Schnelle Suche, Schlüssel in beliebiger Reihenfolge
SortedDictionary<TKey,TValue>
✅ Ja Schlüssel werden automatisch sortiert
SortedList<TKey, TValue>
✅ Ja Schlüssel sortiert, sparsamer im Speicher
(Eigene Klasse, die das Interface implementiert) ✅ Ja Deine eigene Logik, aber du musst den Vertrag einhalten

5. Verbindung zu anderen Collection-Interfaces

Für echte Nerds: Das Interface IDictionary<TKey, TValue> erbt von ICollection<KeyValuePair<TKey, TValue>> und IEnumerable<KeyValuePair<TKey, TValue>>. Das heißt, jedes Wörterbuch kannst du:

  • Mit foreach über Key-Value-Paare durchlaufen,
  • Paare mit Collection-Methoden hinzufügen und entfernen,
  • Die Anzahl der Elemente bekommen.

foreach (var entry in myDictionary)
{
    Console.WriteLine($"{entry.Key} => {entry.Value}");
}

6. Besonderheiten und typische Fehler

Arbeiten mit dem Indexer

Der häufigste Anfängerfehler: Versuchst du, ein Element mit einem nicht vorhandenen Schlüssel zu bekommen, fliegt eine KeyNotFoundException.


var value = myDictionary["NoSuchKey"]; // Boom!

Deshalb immer besser TryGetValue nutzen:


if (myDictionary.TryGetValue("Murzik", out var cat))
{
    Console.WriteLine($"Katze gefunden: {cat}");
}
else
{
    Console.WriteLine($"Katze nicht gefunden!");
}

Hinzufügen eines schon existierenden Schlüssels

Wenn du Add für einen schon vorhandenen Schlüssel aufrufst, gibt's ArgumentException. Wenn du „hinzufügen oder aktualisieren“ willst, nimm den Indexer:


// Fügt hinzu, wenn nicht da, aktualisiert, wenn schon da
myDictionary["Murka"] = new Cat("Murka", 5);

Durchlaufen und Modifizieren

Versuch nicht, das Wörterbuch direkt im foreach-Loop zu ändern (z.B. Elemente zu löschen): Das gibt eine Exception. Wenn du was löschen willst, erstelle zuerst eine Liste mit Schlüsseln zum Entfernen und lösche sie dann in einer separaten Schleife:


// Sicheres Entfernen von Elementen
var keysToRemove = new List<string>();
foreach (var pair in myDictionary)
{
    if (pair.Value.Age > 10) // Bedingung zum Entfernen
    {
        keysToRemove.Add(pair.Key);
    }
}

foreach (var key in keysToRemove)
{
    myDictionary.Remove(key);
}
2
Aufgabe
C# SELF, Level 28, Lektion 4
Gesperrt
Überprüfung des Vorhandenseins eines Schlüssels im Dictionary
Überprüfung des Vorhandenseins eines Schlüssels im Dictionary
1
Umfrage/Quiz
Sammlung-Vertrag, Level 28, Lektion 4
Nicht verfügbar
Sammlung-Vertrag
Grundlegende Collection-Interfaces
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION