Question

How to Iterate Over a Dictionary in C#

csharpdictionaryloops

Question

In C#, I have seen several different ways to iterate over a dictionary. Is there a standard or recommended way to do it?

For example, given a dictionary like this:

var scores = new Dictionary<string, int>
{
    { "Alice", 95 },
    { "Bob", 87 },
    { "Charlie", 91 }
};

What is the usual way to loop through its contents, and when should I iterate over key-value pairs instead of only keys or only values?

Short Answer

By the end of this page, you will understand the standard way to iterate over a Dictionary<TKey, TValue> in C#, how to access keys and values, when to use foreach with KeyValuePair, and which common patterns developers use in real projects.

Concept

A dictionary in C# stores data as key-value pairs. Each key is unique, and each key maps to one value.

When you iterate over a dictionary, the most common goal is one of these:

  • read both the key and the value
  • read only the keys
  • read only the values

The standard way to iterate over a dictionary is with foreach. A Dictionary<TKey, TValue> is enumerable, so you can loop through it directly.

When you do that, each item is a KeyValuePair<TKey, TValue>. That means each loop iteration gives you:

  • item.Key
  • item.Value

Example:

foreach (KeyValuePair<string, int> item in scores)
{
    Console.WriteLine($"{item.Key}: {item.Value}");
}

In modern C#, var is also common:

foreach (var item in scores)
{
    Console.WriteLine($"{item.Key}: {item.Value}");
}

This matters because dictionaries are used everywhere in real applications:

  • caching values by ID
  • storing configuration settings
  • counting occurrences of items
  • looking up data quickly by key
  • processing API response fields

If you need both parts, iterate over the dictionary itself. If you only need one part, use .Keys or .Values for clarity.

Mental Model

Think of a dictionary like a set of labeled drawers.

  • The key is the label on the drawer.
  • The value is what is stored inside.

When you iterate over the whole dictionary, you walk past each drawer and see both the label and the contents.

When you iterate over .Keys, you only read the labels.

When you iterate over .Values, you only inspect the contents.

So the question is simple: what information do you need while looping?

  • Need both label and content? Loop through the dictionary.
  • Need only labels? Loop through Keys.
  • Need only contents? Loop through Values.

That is the mental shortcut most developers use.

Take Quiz

Syntax and Examples

Standard way: iterate over key-value pairs

var scores = new Dictionary<string, int>
{
    { "Alice", 95 },
    { "Bob", 87 },
    { "Charlie", 91 }
};

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

This is the most common and recommended approach when you need both the key and the value.

Iterate over only keys

foreach (var key in scores.Keys)
{
    Console.WriteLine(key);
}

Use this when only the keys matter.

Iterate over only values

foreach (var value in scores.Values)
{
    Console.WriteLine(value);
}

Use this when only the values matter.

Deconstruction syntax

In modern C#, you can deconstruct key-value pairs:

foreach (var (name, score) in scores)
{
    Console.WriteLine($"{name}: {score}");
}

This is often easier to read.

Example: filtering while iterating

foreach (var (name, score) in scores)
{
    if (score >= 90)
    {
        Console.WriteLine($"High score: {name}");
    }
}

This loops through each entry and prints only students with scores of 90 or more.

Step by Step Execution

Consider this code:

var scores = new Dictionary<string, int>
{
    { "Alice", 95 },
    { "Bob", 87 }
};

foreach (var pair in scores)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

Step by step:

  1. A dictionary named scores is created.
  2. It contains two entries:
    • key "Alice" with value 95
    • key "Bob" with value 87
  3. The foreach loop starts.
  4. On the first iteration, pair represents one key-value pair, for example:
    • pair.Key is "Alice"
    • pair.Value is 95
  5. The program prints:
Alice: 95
  1. On the second iteration, pair represents the next entry:
    • pair.Key is "Bob"
    • pair.Value is 87
  2. The program prints:
Bob: 87
  1. The loop ends after all entries are visited.

Important note about order

A dictionary is optimized for lookup by key, not for preserving insertion order as the main idea of the type. In practice, you should not write logic that depends on a specific iteration order unless your chosen collection type guarantees the behavior you need.

Real World Use Cases

Configuration settings

var settings = new Dictionary<string, string>
{
    { "Theme", "Dark" },
    { "Language", "en-US" },
    { "Region", "US" }
};

foreach (var (key, value) in settings)
{
    Console.WriteLine($"{key} = {value}");
}

Useful for printing, validating, or exporting app settings.

Counting occurrences

var wordCounts = new Dictionary<string, int>
{
    { "apple", 3 },
    { "banana", 5 }
};

foreach (var (word, count) in wordCounts)
{
    Console.WriteLine($"{word} appears {count} times");
}

Common in text analysis and reporting.

API or JSON-like field processing

Some applications map field names to values for dynamic processing.

var fields = new Dictionary<string, string>
{
    { "firstName", "Sam" },
    { "lastName", "Lee" }
};

foreach (var (fieldName, fieldValue) in fields)
{
    Console.WriteLine($"Processing {fieldName}: {fieldValue}");
}

Caching

var cache = new Dictionary<int, string>
{
    { 101, "Product A" },
    { 102, "Product B" }
};

foreach (var (id, productName) in cache)
{
    Console.WriteLine($"Cached item {id}: {productName}");
}

Used when reviewing or logging cache contents.

Take Quiz

Real Codebase Usage

In real codebases, developers usually choose the loop style based on what they need.

Common pattern: iterate over the whole dictionary

Use this when you need both key and value.

foreach (var (userId, userName) in users)
{
    logger.LogInformation($"User {userId}: {userName}");
}

Common pattern: validation

foreach (var (field, value) in formData)
{
    if (string.IsNullOrWhiteSpace(value))
    {
        Console.WriteLine($"Missing value for {field}");
    }
}

This is common in request validation and data cleaning.

Common pattern: guard clause before lookup or processing

if (scores.Count == 0)
{
    return;
}

foreach (var (name, score) in scores)
{
    Console.WriteLine($"{name}: {score}");
}

Common pattern: use TryGetValue instead of iterating for one key

If you need just one value, do not loop through the whole dictionary.

if (scores.TryGetValue("Alice", out int score))
{
    Console.WriteLine(score);
}

Common pattern: transform with LINQ when needed

var topStudents = scores
    .Where(pair => pair.Value >= 90)
    .Select(pair => pair.Key)
    .ToList();

Developers often combine dictionary iteration with filtering, projection, and validation.

Avoid modifying during enumeration

A common real-world rule is: do not add or remove dictionary items inside a foreach over that same dictionary.

Common Mistakes

1. Iterating over keys when you really need both key and value

Broken or less clear approach:

foreach (var key in scores.Keys)
{
    Console.WriteLine($"{key}: {scores[key]}");
}

This works, but if you need both key and value, iterating over the dictionary directly is clearer.

Better:

foreach (var pair in scores)
{
    Console.WriteLine($"{pair.Key}: {pair.Value}");
}

2. Expecting a guaranteed order

Beginners sometimes assume the items will always come out in a specific order.

foreach (var pair in scores)
{
    Console.WriteLine(pair.Key);
}

Do not build logic that depends on order unless you use a collection type intended for ordered behavior.

3. Modifying the dictionary during foreach

Broken example:

foreach (var pair in scores)
{
    if (pair.Value < 90)
    {
        scores.Remove(pair.Key);
    }
}

This can throw an exception.

Safer approach:

var keysToRemove = new List<string>();

foreach (var pair in scores)
{
    if (pair.Value < 90)
    {
        keysToRemove.Add(pair.Key);
    }
}

foreach (var key in keysToRemove)
{
    scores.Remove(key);
}

4. Using iteration for lookup

Broken idea:

foreach (var pair in scores)
{
    if (pair.Key == "Alice")
    {
        Console.WriteLine(pair.Value);
    }
}

Better:

if (scores.TryGetValue("Alice", out int score))
{
    Console.WriteLine(score);
}

5. Confusing KeyValuePair with just a value

Broken example:

foreach (var item in scores)
{
    Console.WriteLine(item);
}

This prints the pair object representation, which is usually not what beginners expect.

Better:

foreach (var item in scores)
{
    Console.WriteLine($"{item.Key}: {item.Value}");
}

Comparisons

ApproachBest whenExampleNotes
foreach (var pair in dictionary)You need both key and valuepair.Key, pair.ValueStandard and most common
foreach (var key in dictionary.Keys)You only need keyskeyClear and direct
foreach (var value in dictionary.Values)You only need valuesvalueBest when keys are irrelevant
foreach (var (key, value) in dictionary)You need both, with cleaner syntaxkey, valueNice modern C# style
for loopRarely used with dictionariesNot typicalDictionaries are not index-based

Dictionary iteration vs lookup

TaskBetter choice
Process every entryIterate with foreach
Find one value by keyTryGetValue
Check if a key existsContainsKey or TryGetValue
Use only valuesdictionary.Values

foreach vs for

Featureforeachfor
Works naturally with dictionariesYesNot really
Uses indexesNoYes
Best for collections of entriesYesNo
Beginner readabilityHighLower for dictionaries
Take Quiz

Cheat Sheet

Quick reference

Iterate over key-value pairs

foreach (var pair in dictionary)
{
    Console.WriteLine(pair.Key);
    Console.WriteLine(pair.Value);
}

Iterate over keys only

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

Iterate over values only

foreach (var value in dictionary.Values)
{
    Console.WriteLine(value);
}

Deconstruct pairs

foreach (var (key, value) in dictionary)
{
    Console.WriteLine($"{key}: {value}");
}

Look up one key

if (dictionary.TryGetValue("someKey", out var value))
{
    Console.WriteLine(value);
}

Rules of thumb

  • Use foreach as the standard way to iterate a dictionary.
  • Loop over the dictionary itself when you need both key and value.
  • Use .Keys or .Values when you only need one side.
  • Do not use a for loop unless you have a special reason.
  • Do not modify the dictionary while iterating with foreach.
  • Do not iterate just to find one known key.

Edge case reminders

  • Dictionary iteration order should not be relied on unless the collection type guarantees the behavior you need.
  • Keys are unique.
  • Values do not have to be unique.

FAQ

Is foreach the standard way to iterate over a dictionary in C#?

Yes. foreach is the normal and recommended way to iterate over a Dictionary<TKey, TValue>.

What type do I get when I loop over a dictionary?

Each item is a KeyValuePair<TKey, TValue>, so you can access .Key and .Value.

Should I loop over Keys and then use dictionary[key]?

Only if you truly only need keys. If you need both key and value, iterating over the dictionary directly is usually clearer.

Can I use a for loop with a dictionary?

Not naturally. Dictionaries are not index-based collections, so foreach is the better fit.

Can I change the dictionary while looping through it?

Not safely with a normal foreach. Adding or removing entries during enumeration can cause an exception.

How do I get just one value from a dictionary?

Use TryGetValue instead of iterating through every item.

Is deconstruction a good way to iterate?

Yes, if your C# version supports it. foreach (var (key, value) in dictionary) is often clean and readable.

Take Quiz

Mini Project

Description

Build a simple student score reporter using a C# dictionary. This project demonstrates the standard way to iterate over dictionary entries, print formatted output, and apply a small condition while looping.

It is useful because dictionaries are commonly used to map names, IDs, or codes to values in real applications.

Goal

Create a program that stores student scores in a dictionary, prints every student and score, and highlights students with scores of 90 or higher.

Requirements

  • Create a Dictionary<string, int> with at least four student scores.
  • Iterate over the dictionary using foreach.
  • Print each student's name and score.
  • Print a second message for students whose score is 90 or higher.
Take Quiz

Keep learning

Related questions

View more