Dictionary vs Hashtable in C#: Warum das Dictionary immer gewinnt?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Dictionary vs Hashtable: Der Kampf der Sammlungen in C#

\n\n

Stellen Sie sich folgende Situation vor: Sie schreiben Code in C# und müssen Daten schnell nach einem Schlüssel speichern und abrufen. Sie öffnen die Dokumentation und sehen zwei ähnliche Klassen — Dictionary und Hashtable. Beide arbeiten nach dem Prinzip "Schlüssel-Wert", beide versprechen blitzschnellen Zugriff auf Daten. Aber welche sollen Sie wählen?

\n\n

Wenn Sie sich diese Frage schon einmal gestellt haben, sind Sie nicht allein. Auf Stack Overflow hat das Thema "Why is Dictionary preferred over Hashtable in C#?" tausende Aufrufe und hunderte Stimmen gesammelt. Und heute werden wir diese Frage ein für alle Mal klären. Spoiler: Dictionary gewinnt fast immer. Aber lassen Sie uns herausfinden, warum.

\n\n

Ein kurzer historischer Exkurs: Woher kommt Hashtable?

\n\n

Um das Wesen des Konflikts zu verstehen, müssen wir in die Geschichte von C# eintauchen. Als die .NET-Plattform gerade erschien (Version 1.0), stand Entwicklern die Klasse Hashtable aus dem Namensraum System.Collections zur Verfügung. Es war eine klassische Hash-Tabelle, die beliebige Objekte speichern konnte. Klingt cool, oder? Aber es gab ein Problem — das Fehlen einer Typisierung.

\n\n

Mit der Veröffentlichung von .NET 2.0 und dem Aufkommen von Generics stellte Microsoft eine neue Sammlung vor — Dictionary<TKey, TValue> aus dem Namensraum System.Collections.Generic. Und hier begann die wahre Magie.

\n\n

Typsicherheit: Der Hauptvorteil von Dictionary

\n\n

Schauen wir uns ein konkretes Codebeispiel an. So sieht die Arbeit mit Hashtable aus:

\n\n
// Alter Weg: Hashtable\nHashtable hashtable = new Hashtable();\nhashtable.Add("Schlüssel1", 123);\nhashtable.Add("Schlüssel2", "Zeichenkette"); // Fehler? Nein, wird kompiliert!\nhashtable.Add(456, "noch eine Zeichenkette"); // Der Schlüssel kann auch ein beliebiges Objekt sein\n\n// Jetzt versuchen wir, Daten abzurufen\nint value = (int)hashtable["Schlüssel2"]; // Autsch! InvalidCastException zur Laufzeit!
\n\n

Sehen Sie das Problem? Hashtable akzeptiert beliebige Typen — sowohl für Schlüssel als auch für Werte. Der Compiler lässt jeden Fehler durch, und Sie erfahren davon erst zur Laufzeit des Programms. Das ist ein direkter Weg zu schwer auffindbaren Bugs.

\n\n

Und jetzt schauen wir uns Dictionary an:

\n\n
// Neuer, korrekter Weg: Dictionary\nDictionary<string, int> dictionary = new Dictionary<string, int>();\ndictionary.Add("Schlüssel1", 123);\n// dictionary.Add("Schlüssel2", "Zeichenkette"); // Compilerfehler! Typ stimmt nicht überein\n// dictionary.Add(456, "noch eine Zeichenkette"); // Auch ein Fehler — der Schlüssel muss ein string sein\n\n// Daten ohne Typumwandlung abrufen\nint value = dictionary["Schlüssel1"]; // Sauber, sicher, elegant
\n\n

Dictionary ist typsicher. Sie geben explizit an, welche Typen die Schlüssel und Werte haben. Der Compiler überprüft dies zur Build-Zeit. Keine unerwarteten Ausnahmen zur Laufzeit — der Code funktioniert entweder oder wird nicht kompiliert.

\n\n

Leistung: Wer ist schneller?

\n\n

Der zweite wichtige Aspekt ist die Leistung. Und auch hier liegt Dictionary vorn. Warum? Es geht um Boxing und Unboxing.

\n\n

Wenn Sie mit Hashtable arbeiten, werden alle Werttypen (int, double, struct usw.) in Objekte verpackt. Dies belastet den Garbage Collector und verlangsamt die Arbeit. Lassen Sie uns das in der Praxis überprüfen:

\n\n
// Hashtable: Boxing/Unboxing\nHashtable ht = new Hashtable();\nStopwatch sw = Stopwatch.StartNew();\nfor (int i = 0; i < 1000000; i++)\n{\n    ht.Add(i, i); // Jeder int wird in object verpackt\n}\nsw.Stop();\nConsole.WriteLine($"Hashtable Hinzufügen: {sw.ElapsedMilliseconds} ms");\n\n// Dictionary: ohne Boxing\nDictionary<int, int> dict = new Dictionary<int, int>();\nsw.Restart();\nfor (int i = 0; i < 1000000; i++)\n{\n    dict.Add(i, i); // Kein Boxing — wir arbeiten direkt mit int\n}\nsw.Stop();\nConsole.WriteLine($"Dictionary Hinzufügen: {sw.                

Blogs

Buchempfehlungen