Phase 13 of 30 · Topic 13.2

`Dictionary<TKey, TValue>` Hash Table & Entry Chaining Internals

1Concept

In .NET, `Dictionary<TKey, TValue>` uses two arrays: `int[] _buckets` and `Entry[] _entries`. Keys are mapped to buckets via `hashCode % primeCapacity`. Collisions are resolved using non-allocating linked list indices.

2Architecture Diagram

Key ──> GetHashCode() ──> Bucket Index = (HashCode & 0x7FFFFFFF) % PrimeSize
                               │
                               ▼
        _buckets[Index] ──> Index into `_entries[i]` (Contains Key, Value, Next Index)

3Code Example

C# 13 & .NET 9
using System;
using System.Collections.Generic;

public class DictionaryInternalsDemo
{
    public static void Main()
    {
        // Pre-allocated dictionary with prime capacity
        var dict = new Dictionary<string, int>(capacity: 100, StringComparer.Ordinal)
        {
            ["AuthToken"] = 9021,
            ["SessionId"] = 4410
        };

        if (dict.TryGetValue("AuthToken", out int token))
        {
            Console.WriteLine($"Found Token in O(1): {token}");
        }
    }
}

4Expected Output

Found Token in O(1): 9021

5Key Takeaways

  • Always specify `StringComparer.Ordinal` for ASCII/machine string keys for 3x faster hash comparisons.
  • Use `TryGetValue()` to avoid double lookups (`ContainsKey()` + `dict[key]`).
  • Use `CollectionsMarshal.GetValueRefOrAddDefault` (.NET 6+) for zero-lookup dictionary mutations.