Introduction

If you’ve been working with C# for any length of time, you’ve probably needed to store data as key-value pairs. The two main contenders for this job are Dictionary<TKey, TValue> and HashTable. They both do similar things, but there are some crucial differences that might make you choose one over the other.

In this post, I’ll walk you through both options so you can make the right choice for your project. Trust me, this decision matters more than you might think!

Dictionary<TKey, TValue>: The Modern Approach

Dictionary is the newer kid on the block, introduced in .NET 2.0 with the generic collections framework. It’s basically a specialized hash table that lets you specify the exact types for your keys and values.

What Makes Dictionary Great

Dictionary has become my go-to choice for most projects, and here’s why:

First off, it’s type-safe. The compiler checks your types, so you won’t accidentally try to store a string where an integer should go. This catches a ton of potential bugs before your code even runs.

It’s also faster in most real-world scenarios. Since Dictionary knows exactly what types it’s dealing with, it doesn’t need to perform type conversions behind the scenes (no boxing and unboxing of value types).

Here’s a simple example of Dictionary in action:

// Creating a Dictionary to store people's ages
var peopleAges = new Dictionary<string, int>();

// Adding some people to our collection
peopleAges.Add("Alice", 25);
peopleAges.Add("Bob", 32);
peopleAges["Charlie"] = 29;  // You can also use this syntax

// Getting someone's age is straightforward
int alicesAge = peopleAges["Alice"];  // No casting needed!

// A safer way to get values
if (peopleAges.TryGetValue("Bob", out int bobsAge))
{
    Console.WriteLine($"Bob is {bobsAge} years old");
}

// Checking if someone is in our Dictionary
if (!peopleAges.ContainsKey("David"))
{
    Console.WriteLine("David isn't in our list");
}

// Looping through everyone
foreach (var person in peopleAges)
{
    Console.WriteLine($"{person.Key} is {person.Value} years old");
}

Notice how clean this code is? No casting, no type conversion, just pure simplicity.

HashTable: The Original Solution

Hashtable has been around since .NET 1.0. It’s the grandparent of Dictionary and works similarly but with some important differences.

When Hashtable Might Be Useful

There are still scenarios where you might want to use Hashtable:

Hashtable is non-generic, meaning it stores everything as objects. This is both its weakness and its strength. It’s less type-safe, but it gives you more flexibility when you need to mix different types in the same collection.

It can also be made thread-safe with Hashtable.Synchronized(), which might be useful in certain multi-threaded scenarios.

Here’s how you’d use a Hashtable:

// Creating a Hashtable
Hashtable mixedData = new Hashtable();

// Adding various items
mixedData.Add("Alice", 25);
mixedData.Add(42, "The answer");  // Notice how we can mix key types
mixedData.Add("IsValid", true);   // And value types too

// When getting values, we need to cast
int alicesAge = (int)mixedData["Alice"];  // Casting required

// Checking for existence works the same way
bool hasAnswer = mixedData.ContainsKey(42);  // true

// Looping through items
foreach (DictionaryEntry item in mixedData)
{
    Console.WriteLine($"Key: {item.Key}, Value: {item.Value}");
}

// If you need thread safety
Hashtable threadSafe = Hashtable.Synchronized(mixedData);

The main downside? That casting. It’s not just extra code to write, it can cause runtime errors if you cast to the wrong type.

The Real-World Differences

Let me break down the practical differences that will affect your day-to-day coding:

  1. Performance: Dictionary is typically 10-25% faster for lookups and insertions, especially with value types. Why? Because Hashtable needs to box and unbox value types, which adds overhead.

  2. Code safety: With Dictionary, most errors are caught at compile time. With Hashtable, you might not discover type mismatches until your code is running in production.

  3. Modern features: Dictionary works smoothly with LINQ and other modern C# features. Hashtable predates these features, so integration isn’t as seamless.

  4. Special cases: Hashtable allows null keys; Dictionary doesn’t. Hashtable can mix different key types in the same collection; Dictionary enforces a consistent key type.

Here’s a quick comparison table:

FeatureDictionary<TKey, TValue>Hashtable
Type SafetyStrong (compile-time)Weak (runtime)
PerformanceBetter for value typesSlower due to boxing
Memory UsageMore efficientLess efficient
Thread SafetyNot thread-safe by defaultCan be synchronized
Null KeysNot allowedAllowed
Mixed TypesNot allowedAllowed
LINQ SupportFull supportLimited support

Which Should You Choose?

After years of working with both, here’s my advice:

Use Dictionary when:

  • You’re starting a new project
  • You care about code safety and catching errors early
  • Performance matters to you
  • You’re working with a specific, known set of types

Use Hashtable when:

  • You’re maintaining legacy code that already uses it
  • You genuinely need to mix different types of keys or values
  • You specifically need thread-safety features
  • You need to support null keys

Wrapping Up

For most modern C# applications, Dictionary is the clear winner. It gives you better type safety, better performance, and integrates more smoothly with the rest of the C# ecosystem.

That said, Hashtable isn’t completely obsolete. There are still edge cases where its flexibility might be exactly what you need. Just be aware that this flexibility comes at the cost of safety and performance.

In my own code, I reach for Dictionary by default and only use Hashtable when I have a specific reason to. That approach has served me well, and I’d recommend the same to you.