C# Dictionary:

Dictionary in C# is same as English dictionary. English dictionary is a collection of words and their definitions, often listed alphabetically in one or more specific languages. In the same way, the Dictionary in C# is a collection of Keys and Values, where key is like word and value is like definition.

Every class includes System.Collection.Generics namespace by default while creating a new class in visual studio.

Dictionary<TKey, TValue> is a generic collection included in the System.Collection.Generics namespace. TKey denotes the type of key and TValue is the type of TValue.

Dictionary Initialization:

A Dictionary can be initialized with a variable of IDictionary<Tkey, TValue> interface as well as with a Dictionary<TKey, Tvalue> class:

Example: Dictionary Initialization

IDictionary<int, string> dict = new Dictionary<int, string>();
        
//or

Dictionary<int, string> dict = new Dictionary<int, string>();

In the above example, we have specified types of key and value while declaring a dictionary object. An int is a type of key and string is a type of value that will be stored into a dictionary object named dict. You can use any valid C# data type for keys and values.

It is recommended to program to the interface rather than to the class. So, use IDictionary<TKey, TValue> type variable to initialize a dictionary object.

Note : Dictionary cannot include duplicate or null keys, where as values can be duplicated or set as null. Keys must be unique otherwise it will throw a runtime exception.

Important Properties and Methods of IDictionary<TKey, TValue>:

Property Description
Count Gets the total number of elements exists in the Dictionary<TKey,TValue>.
IsReadOnly Returns a boolean indicating whether the Dictionary<TKey,TValue> is read-only.
Item Gets or sets the element with the specified key in the Dictionary<TKey,TValue>.
Keys Returns collection of keys of Dictionary<TKey,TValue>.
Values Returns collection of values in Dictionary<TKey,TValue>.
Method Description
void Add(T) Adds an item to the Dictionary collection.
void Add(TKey key, TValue value) Add key-value pairs in Dictionary<TKey, TValue> collection.
void Remove(T item) Removes the first occurance of specified item from the Dictionary<TKey, TValue>.
void Remove(TKey) Removes the element with the specified key.
bool ContainsKey(TKey key) Checks whether the specified key exists in Dictionary<TKey, TValue>.
bool ContainsValue(TValue value) Checks whether the specified key exists in Dictionary<TKey, TValue>.
void Clear() Removes all the elements from Dictionary<TKey, TValue>.
bool TryGetValue(TKey key, out TValue value) Returns true and assigns the value with specified key, if key does not exists then return false.

Add Elements into Dictionary:

Use Add() method to add the key-value pair in dictionary.

Add() Signature: void Add(TKey, Tvalue)

Example: Add elements in dictionary

IDictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");

Check whether a dictionary already stores specified key before adding a key-value pair.

The IDictionary type instance has one more overload for the Add() method. It accepts a KeyValuePair<TKey, TValue> struct as a parameter.

Add() Signature:void Add(KeyValuePair<TKey,TValue> item);

Example: Add key-value pair in dictionary

IDictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(new KeyValuePair<int, string>(1, "One"));
dict.Add(new KeyValuePair<int, string>(2, "Two"));

//The following is also valid
dict.Add(3, "Three");

It can also be initialized using collecton initializer syntax with keys and values as shown below.

Example: Dictionary Initialization using object initializer syntax

IDictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };

Access Dictionary Elements:

Dictionary elements can be accessed by many ways e.g. foreach, for loop or indexer.

Use foreach or for loop to iterate access all the elements of dictionary. The dictionary stores key-value pairs. So you can use a KeyValuePair<TKey, TValue> type or an implicitly typed variable var in foreach loop as shown below.

Example: Access elements using foreach

Dictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };

foreach (KeyValuePair<int, string> item in dict)
{
    Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
Output:
Key: 1, Value: One
Key: 2, Value: Two
Key: 3, Value: Three

Use for loop to access all the elements. Use Count property of dictionary to get the total number of elements in the dictionary.

Example: Access elements using for loop

Dictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };


for (int i = 0; i < dict.Count; i++)
{
    Console.WriteLine("Key: {0}, Value: {1}", 
                                            dict.Keys.ElementAt(i), 
                                            dict[ dict.Keys.ElementAt(i)]);
}

Output:
Key: 1, Value: One
Key: 2, Value: Two
Key: 3, Value: Three

Dictionary can be used like an array to access its individual elements. Specify key (not index) to get a value from a dictionary using indexer like an array.

Example: Access Individual Element

Dictionary<int, string> dict = new Dictionary<int, string>()
                                                            {
                                                                {1,"One"},
                                                                {2, "Two"},
                                                                {3,"Three"}
                                                            };

Console.WriteLine(dict[1]); //returns One
Console.WriteLine(dict[2]); // returns Two

Output:
One
Two
Note : Indexer takes the key as a parameter. If the specified key does not exist then a KeyNotFoundException will be thrown.

If you are not sure about the key then use the TryGetValue() method. The TryGetValue() method will return false if it could not found keys instead of throwing an exception.

TryGetValue() Signature: bool TryGetValue(TKey key, out TValue value)

Example: TryGetValue()

Dictionary<int, string> dict = new Dictionary<int, string>()
                                {
                                    {1,"One"},
                                    {2, "Two"},
                                    {3,"Three"}
                                };

string result;

if(dict.TryGetValue(4, out result))
{
    Console.WriteLine(result);
}
else
{
    Console.WriteLine("Could not find the specified key.");
}
Output:
Could not find the specified key.

Check for existing elements:

Dictionary includes various methods to determine whether a dictionary contains specified elements or keys. Use the ContainsKey() method to check whether a specified key exists in the dictionary or not.

Use the Contains() method to check whether a specified Key and Value pair exists in the dictionary or not.

ContainsKey() Signature: bool ContainsKey(TKey key)

Contains() signature: bool Contains(KeyValuePair<TKey, TValue> item)

Example: ContainsKey() & Contains()

Dictionary<int, string> dict = new Dictionary<int, string>()
                                            {
                                                {1,"One"},
                                                {2, "Two"},
                                                {3,"Three"}
                                            };
dict.ContainsKey(1); // returns true
dict.ContainsKey(4); // returns false

dict.Contains(new KeyValuePair<int,string>(1,"One")); // returns true

Another overload of the Contains() method takes IEqualityComperer as a second parameter. An instance of IEqualityComparer is used when you want to customize the equality comparison. For example, consider the following example of a dictionary that stores a Student objects.

Example: Custom comparer with Dictionary

public class Student
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
}

class StudentDictionaryComparer : IEqualityComparer<KeyValuePair<int,Student>>
{
    public bool Equals(KeyValuePair<int, Student> x, KeyValuePair<int, Student> y)
    {
        if (x.Key == y.Key && (x.Value.StudentID == y.Value.StudentID) && (x.Value.StudentName == y.Value.StudentName))
            return true;

        return false;
    }

    public int GetHashCode(KeyValuePair<int, Student> obj)
    {
        return obj.Key.GetHashCode();
    }
}

class Program
{

    static void Main(string[] args)
    {
        IDictionary<int, Student> studentDict = new Dictionary<int, Student>()
                    {
                        { 1, new Student(){ StudentID =1, StudentName = "Bill"}},
                        { 2, new Student(){ StudentID =2, StudentName = "Steve"}},
                        { 3, new Student(){ StudentID =3, StudentName = "Ram"}}
                    };

        Student std = new Student(){ StudentID = 1, StudentName = "Bill"};

        KeyValuePair<int, Student> elementToFind = new KeyValuePair<int, Student>(1, std);

        bool result = studentDict.Contains(elementToFind, new StudentDictionaryComparer()); // returns true
    
        Console.WriteLine(result);
    }
}

Output:
true

In the above example, we have used StudentDictionaryComparer which derives IEqualityComparer to compare Student objects in the dictionary. The default comparer will only work with primitive data types.

Remove Elements in Dictionary:

Use the Remove() method to remove an existing item from the dictionary. Remove() has two overloads, one overload method accepts a key and the other overload method accepts a KeyValuePair<> as a parameter.

Remove() signature:

  • bool Remove(TKey key)
  • bool Remove(KeyValuePair<TKey,TValue>)
Example: Remove elements from Dictionary

Dictionary<int, string> dict = new Dictionary<int, string>()
                                            {
                                                {1,"One"},
                                                {2, "Two"},
                                                {3,"Three"}
                                            };

dict.Remove(1); // removes the item which has 1 as a key

Both Key and Value must match to remove an item. The item will not be removed if both are not matched. For example, the following example will not remove any item:


// removes nothing because value One1 is not matching
dict.Remove(new KeyValuePair<int, string>(2, "Two1")); 

Points to Remember :

  1. A Dictionary stores Key-Value pairs where the key must be unique.
  2. Before adding a KeyValuePair into a dictionary, check that the key does not exist using the ContainsKey() method.
  3. Use the TryGetValue() method to get the value of a key to avoid possible runtime exceptions.
  4. Use a foreach or for loop to iterate a dictionary.
  5. Use dictionary indexer to access individual item.
  6. Use custom class that derives IEqualityComparer to compare object of custom class with Contains() method.