Start learning free

LESSON 128 OF 674 · DICTIONARIES

Checking for a Key in a C# Dictionary with ContainsKey

Lesson Read the full explanation

TL ; DR:

Call d.ContainsKey(key) to ask whether a Dictionary has a key. It returns true or false, so it goes in an if.


Dictionary<string, string> capitals = new Dictionary<string, string>();
capitals["France"] = "Paris";
capitals["Japan"] = "Tokyo";

if (capitals.ContainsKey("Japan")) {
    Console.WriteLine(capitals["Japan"]);   // Tokyo
}

if (!capitals.ContainsKey("Spain")) {
    Console.WriteLine("No Spain");          // No Spain
}


Full lesson:

Reading a missing key is an error. capitals["Spain"] throws a KeyNotFoundException.

So check first. capitals.ContainsKey("Spain") is true when "Spain" is a key. It is false when it isn't.

Put ! in front for the opposite. !capitals.ContainsKey("Spain") is true here.

A value is not a key

ContainsKey looks only at the keys. capitals.ContainsKey("Paris") is false, because "Paris" is a value.

To look in the values, call ContainsValue("Paris").

A key must match exactly, upper and lower case too. capitals.ContainsKey("japan") is false.


Your task

In pets, each key is a pet's name, and its value is the pet's kind.

First, check whether "Tom" is a key of pets. If it is, print Tom is a followed by Tom's kind.

Then check that "cat" is not a key, with ! and ContainsKey. If so, print cat is not a key.

"cat" is in pets, but only as a value. It is Tom's kind.

Expected output:

Tom is a cat
cat is not a key
STEP 1 OF 2
    Ctrl + Enter to check

    C# · DICTIONARIES

    Dictionary Key Check in C#, explained

    Why check before reading

    A Dictionary<TKey, TValue> looks up values by key. Reading a key that is not there is an error, not an empty answer: capitals["Spain"] throws a KeyNotFoundException with the message "The given key 'Spain' was not present in the dictionary." So when a key might be missing, ask first.

    ContainsKey(key) returns true when the key is in the dictionary and false when it is not. It returns a bool, so it can be the condition of an if.

    Dictionary<string, string> capitals = new Dictionary<string, string>();
    capitals["France"] = "Paris";
    capitals["Japan"] = "Tokyo";
    if (capitals.ContainsKey("Japan")) {
        Console.WriteLine(capitals["Japan"]);
    }
    if (!capitals.ContainsKey("Spain")) {
        Console.WriteLine("No Spain");
    }
    
    Tokyo
    No Spain
    

    Inside the first if, reading capitals["Japan"] is safe, because the check has just shown that the key exists. Putting ! in front reverses the answer, so the second condition is true for a missing key. In a file of your own, add using System; and using System.Collections.Generic;.

    An else branch covers the other case. Say the variable key holds "Spain":

    if (capitals.ContainsKey(key)) {
        Console.WriteLine(capitals[key]);
    } else {
        Console.WriteLine("Unknown country: " + key);
    }
    

    With the dictionary above, this prints Unknown country: Spain, and the program carries on instead of crashing.

    A value is not a key

    ContainsKey looks only at the keys. In the dictionary above, capitals.ContainsKey("Paris") is false, because "Paris" is a value. To look through the values, call ContainsValue("Paris"), which is true. Keys are the fast side of a dictionary. A value check has to compare against the values one at a time.

    Keys must also match exactly, including upper and lower case. capitals.ContainsKey("japan") is false, since the key is "Japan".

    The exercise, step by step

    In pets, each key is a pet's name and each value is its kind: Rex is a dog, Tom is a cat and Polly is a parrot.

    1. Is Tom a key? Write an if on pets.ContainsKey("Tom"). Inside it, print "Tom is a " followed by pets["Tom"]. The read cannot throw here.
    2. Is "cat" not a key? Write an if on !pets.ContainsKey("cat"). The word "cat" does appear in pets, but only as Tom's kind, which is a value. As a key it is missing, so the condition is true and the line is printed.
    Dictionary<string, string> pets = new Dictionary<string, string>();
    pets["Rex"] = "dog";
    pets["Tom"] = "cat";
    pets["Polly"] = "parrot";
    if (pets.ContainsKey("Tom")) {
        Console.WriteLine("Tom is a " + pets["Tom"]);
    }
    if (!pets.ContainsKey("cat")) {
        Console.WriteLine("cat is not a key");
    }
    
    Tom is a cat
    cat is not a key
    

    A shortcut and some traps

    • One lookup instead of two. ContainsKey followed by an index looks the key up twice. TryGetValue does both in one call. if (capitals.TryGetValue("Japan", out string city)) is true when the key exists, and then city holds the value. When the key is missing, it returns false and city is the default for its type, which is null for a string. Use ContainsKey when you only need the yes or no.
    • Mixing up keys and values. Check the side you mean: ContainsKey for names, ContainsValue for kinds.
    • Different case. "tom" is not "Tom". If you want keys to ignore case, create the dictionary with a comparer: new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase). Then ContainsKey("japan") finds "Japan".
    • Reading before checking. The whole point of the check is to keep the index read out of the missing-key case.

    Key takeaways

    • d.ContainsKey(key) returns true or false and goes in an if.
    • It checks keys only. ContainsValue checks values.
    • Reading a missing key with d[key] throws a KeyNotFoundException.
    • TryGetValue checks and reads in one call.
    Keep going with C#500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free