C#
dictionaries
data comparison
programming
.NET

How to compare two Dictionaries in C

Master System Design with Codemia

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

Introduction

Comparing two dictionaries in C# is less about syntax and more about deciding what equality should mean. Do you only care that the same keys exist, or do you need both keys and values to match exactly? Once that definition is clear, the implementation is straightforward and usually does not require anything more complicated than a count check and key-by-key comparison.

What Dictionary Equality Usually Means

For most applications, two dictionaries are equal if all of these are true:

  • both contain the same number of entries
  • every key in the first dictionary exists in the second
  • the value for each matching key is equal

Dictionary order does not matter. A Dictionary<TKey, TValue> is not a sequence, so using sequence-based comparison carelessly can lead to wrong results if the enumeration order differs.

A Practical Equality Method

The safest general-purpose approach is to iterate through one dictionary and check the other with TryGetValue.

csharp
1using System;
2using System.Collections.Generic;
3
4public static class DictionaryComparer
5{
6    public static bool AreEqual<TKey, TValue>(
7        IDictionary<TKey, TValue> first,
8        IDictionary<TKey, TValue> second)
9    {
10        if (ReferenceEquals(first, second))
11            return true;
12
13        if (first is null || second is null)
14            return false;
15
16        if (first.Count != second.Count)
17            return false;
18
19        var valueComparer = EqualityComparer<TValue>.Default;
20
21        foreach (var pair in first)
22        {
23            if (!second.TryGetValue(pair.Key, out var otherValue))
24                return false;
25
26            if (!valueComparer.Equals(pair.Value, otherValue))
27                return false;
28        }
29
30        return true;
31    }
32}

Example usage:

csharp
1var left = new Dictionary<string, int>
2{
3    ["apples"] = 3,
4    ["oranges"] = 2
5};
6
7var right = new Dictionary<string, int>
8{
9    ["oranges"] = 2,
10    ["apples"] = 3
11};
12
13Console.WriteLine(DictionaryComparer.AreEqual(left, right));

This prints True, even though the insertion order was different.

Comparing Only Keys or Only Values

Sometimes full equality is more than you need. If you only care about keys, compare the key sets.

csharp
1using System;
2using System.Collections.Generic;
3using System.Linq;
4
5var first = new Dictionary<string, int>
6{
7    ["a"] = 1,
8    ["b"] = 2
9};
10
11var second = new Dictionary<string, int>
12{
13    ["b"] = 99,
14    ["a"] = 42
15};
16
17bool sameKeys = first.Keys.OrderBy(k => k)
18                          .SequenceEqual(second.Keys.OrderBy(k => k));
19
20Console.WriteLine(sameKeys);

That approach sorts keys first so order does not distort the result. For large dictionaries, a hash-set-based comparison may be cheaper than sorting.

If you only care about values, the meaning becomes trickier because duplicates matter. A dictionary is key-based by nature, so value-only comparison is usually a specialized requirement rather than the default.

Custom Value Comparisons

The generic method above uses EqualityComparer<TValue>.Default, which works well for primitive types, strings, records, and types that implement meaningful equality.

For complex reference types, you may need to compare selected properties instead. In that case, pass a custom comparer.

csharp
1using System;
2using System.Collections.Generic;
3
4public static bool AreEqual<TKey, TValue>(
5    IDictionary<TKey, TValue> first,
6    IDictionary<TKey, TValue> second,
7    IEqualityComparer<TValue> comparer)
8{
9    if (ReferenceEquals(first, second))
10        return true;
11
12    if (first is null || second is null)
13        return false;
14
15    if (first.Count != second.Count)
16        return false;
17
18    foreach (var pair in first)
19    {
20        if (!second.TryGetValue(pair.Key, out var otherValue))
21            return false;
22
23        if (!comparer.Equals(pair.Value, otherValue))
24            return false;
25    }
26
27    return true;
28}

That makes the comparison logic reusable without rewriting the loop.

Why SequenceEqual Can Mislead

A common shortcut is converting dictionaries to sequences and calling SequenceEqual. That only works reliably if both sequences are ordered in the same way first.

csharp
bool equal = first.OrderBy(p => p.Key)
                  .SequenceEqual(second.OrderBy(p => p.Key));

This can be acceptable for small dictionaries, but it does extra sorting work and is less direct than TryGetValue.

The key point is that raw dictionary enumeration order is not a good basis for equality.

Common Pitfalls

The most common mistake is comparing dictionaries with SequenceEqual without ordering them first. Two equal dictionaries can enumerate differently.

Another issue is relying on reference equality for value objects that should be compared by content. If TValue is a custom class without a proper equality implementation, dictionary comparison can appear to fail for identical-looking data.

Developers also sometimes forget null handling. Comparison helpers should define what happens when either input is null.

Finally, choose the comparison goal carefully. Comparing only keys, only values, or the full dictionary are three different problems and should not share the same helper by accident.

Summary

  • Full dictionary equality means same keys and equal values, regardless of order.
  • 'TryGetValue with a count check is the clearest comparison strategy.'
  • Use EqualityComparer<TValue>.Default unless your value type needs custom logic.
  • Do not rely on raw enumeration order for equality checks.
  • Decide first whether you need key equality, value equality, or complete equality.

Course illustration
Course illustration

All Rights Reserved.