C#
.NET
Programming
Data Structures
Interface Comparison

ILookup interface vs IDictionary

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

ILookup and IDictionary both map keys to values, but they solve different problems in .NET. Choosing the wrong one usually leads to extra code, poor readability, or unnecessary allocations. This guide compares their behavior, performance tradeoffs, and the situations where each type is the better fit.

Core Topic Sections

Core semantic difference

IDictionary maps one key to one value. If you assign a key again, the previous value is replaced unless you prevent it.

ILookup maps one key to many values. Each key returns a sequence, even if only one element exists.

This single difference changes API design:

  1. Dictionary is ideal for mutable key-value state.
  2. Lookup is ideal for grouped read-only query results.

Mutability and lifecycle

Dictionary is mutable. You can add, update, and remove entries after creation.

Lookup is effectively immutable from consumer code. Most lookups are created through LINQ ToLookup, then treated as a query result snapshot.

Mutable and immutable collection behavior should follow your workflow:

  1. Ongoing updates, use dictionary.
  2. Group once and read many times, use lookup.

Basic dictionary usage

csharp
1using System;
2using System.Collections.Generic;
3
4public static class DictionaryExample
5{
6    public static void Main()
7    {
8        IDictionary<string, int> scores = new Dictionary<string, int>();
9        scores["alice"] = 92;
10        scores["bob"] = 87;
11        scores["alice"] = 95; // replace existing value
12
13        Console.WriteLine(scores["alice"]);
14
15        if (scores.TryGetValue("carol", out int value))
16        {
17            Console.WriteLine(value);
18        }
19        else
20        {
21            Console.WriteLine("carol not found");
22        }
23    }
24}

Dictionary gives direct key access and fast updates, which is useful in caches and request-scoped accumulators.

Basic lookup usage

csharp
1using System;
2using System.Linq;
3
4public record Order(string Customer, int Amount);
5
6public static class LookupExample
7{
8    public static void Main()
9    {
10        var orders = new[]
11        {
12            new Order("alice", 100),
13            new Order("bob", 75),
14            new Order("alice", 150)
15        };
16
17        var byCustomer = orders.ToLookup(o => o.Customer, o => o.Amount);
18
19        foreach (int amount in byCustomer["alice"])
20        {
21            Console.WriteLine(amount);
22        }
23
24        Console.WriteLine("Missing key count: " + byCustomer["carol"].Count());
25    }
26}

Lookup indexing is convenient because missing keys return an empty sequence instead of throwing an exception.

Missing key behavior matters

Dictionary index access for a missing key throws. You often need TryGetValue to stay safe.

Lookup index access for a missing key returns an empty enumerable. That makes query pipelines simpler because you can iterate without defensive checks.

This behavior is often the deciding factor in reporting and analytics code where sparse keys are normal.

Performance considerations

Dictionary lookup is usually very fast for single-value retrieval and updates. It is the right choice for hot code paths that mutate state.

Lookup has upfront grouping cost when calling ToLookup, but retrieval by key is efficient afterward. It performs well when the grouped result is reused many times.

If you only need one grouped pass, GroupBy might be enough. If you repeatedly query by key, materializing a lookup usually pays off.

API design guidance

Use dictionary in service code when your object owns mutable state. Use lookup at boundaries where you return grouped read-only data.

A practical pattern is:

  1. Ingest mutable events into dictionary-based structures.
  2. Publish query-friendly grouped projections as lookup or immutable DTO collections.

This separates write concerns from read concerns and reduces accidental mutation.

Converting between the two

Sometimes you need both representations:

  1. Dictionary to lookup: project values then call ToLookup.
  2. Lookup to dictionary: aggregate each grouping to one representative value.

When converting lookup to dictionary, define how to collapse multiple values per key. Common options are first value, last value, sum, or custom merge rule.

Common Pitfalls

  • Using dictionary when a key naturally has multiple values and then storing lists manually.
  • Using lookup for mutable workflows and fighting its read-only design.
  • Accessing dictionary index directly on uncertain keys and triggering exceptions.
  • Building lookup repeatedly in loops instead of creating it once and reusing it.
  • Converting grouped data to dictionary without defining deterministic merge rules.

Summary

  • IDictionary is one key to one mutable value.
  • ILookup is one key to many read-only values.
  • Dictionary is best for mutable state and direct updates.
  • Lookup is best for grouped query results and sparse-key reads.
  • Choose based on mutation needs, missing-key behavior, and reuse pattern.

Course illustration
Course illustration

All Rights Reserved.