Home

.NET Framwork Collections: Dictionary-Based Collections

   

Introduction to Dictionaries

 

Description

A dictionary is a list of items with the following two rules:

  • Each item is a combination of a key and a value. An item can be made of three parts: a key, a value, and a correspondence between them. The correspondence can be represented by the assignment operator: Key=Value. In some environments, the = operator is used. In some others, the : operator is used. Yet in some others, there is no actual operator that joins both sides but you must know that the key and the value go in pair
  • As each item is a combination of a key and a value, each key must be unique. The list of items in the dictionary can be very huge, sometimes in the thousands or even millions. Among the items, each key must be distinct from any other key in the dictionary

In some cases, in addition to these two rules, the items should - in some cases must - be ordered. To order the items, the keys are used. Because in most cases a dictionary is made of words, the keys are ordered in alphabetical order. A dictionary can also be made of items whose keys are date values. In this case, the items would be ordered in chronological order.

There are various types of dictionary types of list used in daily life. The word "dictionary" here does not imply the traditional dictionary that holds the words and their meanings in the English language. The concept is applied in various scenarios.

Creating a Dictionary-Based Collection Class

To support dictionary-based lists, the .NET Framework provides various interfaces and classes. The interfaces allow you to create your own dictionary type of collection class. The classes allow you to directly create a dictionary-based list with an already built-in functionality. The NET Framework provides support for dictionary-based collections through two classes: Hashtable and SortedList. Both classes implement:

  • The IDictionary: This makes it possible to use the DictionaryEntry class to access a key/value item
  • The ICollection: This makes it possible to know the number of items in the list
  • The IEnumerable: This makes it possible to use the foreach loop to enumerate the members of the list
  • And the ICloneable interfaces.

The Hashtable class implements the ISerializable interface, which makes it possible for the list to be serialized. Still, the SortedList class is marked with the Serializable attribute, which makes it possible to file process its list.

The .NET Framework also provides dictionary-types through generic classes. From the System.Collections.Generic namespace, to create a dictionary type of collection, you can use either the Dictionary, the SortedDictionary, or the SortedList class. The System.Collections.Generic.Dictionary class is equivalent to the System.Collections.Hashtable class. The System.Collections.Generic.SortedList class is equivalent to the System.Collections.SortedList class. The System.Collections.Generic.SortedDictionary class is equivalent to the System.Collections.Generic.SortedList class with some differences in the way both classes deal with memory management.

If you decide to use either the System.Collections.Generic.Dictionary or the System.Collections.Generic.SortedList class, when declaring the variable, you must remember to specify the name of the class whose collection is being created.

Before using a dictionary-type of list, you can declare a variable using one of the constructors of the class. Here is an example:

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;

public class Exercise : Form
{
    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        Text = "Students";
        Load += new EventHandler(StartForm);
    }

    void StartForm(object sender, EventArgs e)
    {
        Hashtable Students = new Hashtable();
    }
}

public class Program
{
    static int Main()
    {
        System.Windows.Forms.Application.Run(new Exercise());
        return 0;
    }
}

In this case, the primary list would be empty.

Adding Items to the Collection

To add an item to the list, you can call the Add() method. The syntax of the System.Collections.table.Add() and the System.Collections.SortedList.Add() methods is:

public virtual void Add(object Key, object Value);

The syntax of the System.Collections.Generic.Dictionary.Add(), the System.Collections.Generic.SortedDictionary.Add(), and the System.Collections.Generic.SortedList.Add() method is:

public void Add(TKey key, TValue value);

As you can see, you must provide the key and the value as the first and second arguments to the method respectively. Here are examples of calling the Add() method:

void StartForm(object sender, EventArgs e)
{
    Hashtable Students = new Hashtable();

    Students.Add("Hermine", "Tolston");
    Students.Add("Patrick", "Donley");
}

When calling the Add() method, you must provide a valid Key argument: it cannot be null. For example, the following code would produce an error:

void StartForm(object sender, EventArgs e)
{
    Hashtable Students = new Hashtable();

    Students.Add("Hermine", "Tolston");
    Students.Add("Patrick", "Donley");
    Students.Add(null, "Hannovers");
}

This would produce:

When adding the items to the list, as mentioned in our introduction, each key must be unique: you cannot have two exact keys. If you try adding a key that exists already in the list, the compiler would throw an ArgumentException exception. Based on this, the following code would not work because, on the third call, a "Patrick" key exists already:

void StartForm(object sender, EventArgs e)
{
    Hashtable Students = new Hashtable();

    Students.Add("Hermine", "Tolston");
    Students.Add("Patrick", "Donley");
    Students.Add("Chrissie", "Hannovers");
    Students.Add("Patrick", "Herzog");
}

This would produce:

This means that, when creating a dictionary type of list, you must define a scheme that would make sure that each key is unique among the other keys in the list.

Besides the Add() method, you can use the indexed property to add an item to the collection. To do this, enter the Key in the square brackets of the property and assign it the desired Value. Here is an example:

void StartForm(object sender, EventArgs e)
{
    Hashtable Students = new Hashtable();

    Students.Add("Hermine", "Tolston");
    Students.Add("Patrick", "Donley");
    Students.Add("Chrissie", "Hannovers");
    Students.Add("Patricia", "Herzog");
    Students["Michael"] = "Herlander";
}

Accessing the Items of a Dictionary-Type of List

Although, or because, the key and value are distinct, to consider their combination as a single object, if you are using either the System.Collections.Hasthtable or the System.Collections.SortedList class, the .NET Framework provides the DictionaryEntry structure. To access an item, you can use the foreach loop to visit each item.

To support the foreach loop, the System.Collections.Hashtable and the System.Collections.SortedList classes implement the IEnumerable.GetEnumerator() method. In this case, the item is of type DictionaryEntry: it contains a Key and a Value in combination.

The DictionaryEntry structure contains two properties named Key and Value to identify the components of a combination. Here is an example:

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;

public class Exercise : Form
{
    ListBox lbxStudents;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        Text = "Students";
        lbxStudents = new ListBox();
        lbxStudents.Location = new Point(12, 12);
        Controls.Add(lbxStudents);

        Load += new EventHandler(StartForm);
    }

    void StartForm(object sender, EventArgs e)
    {
        Hashtable Students = new Hashtable();

        Students.Add("Hermine", "Tolston");
        Students.Add("Patrick", "Donley");
        Students.Add("Chrissie", "Hannovers");
        Students.Add("Patricia", "Herzog");
        Students["Michael"] = "Herlander";

        foreach (DictionaryEntry entry in Students)
            lbxStudents.Items.Add(entry.Key + " " + entry.Value);
    }
}

This would produce:

If you are using a generic class, the .NET Framework provides the KeyValuePair structure that follows the same functionality as the System.Collections.DictionaryEntry structure, except that you must apply the rules of generic classes.

The Hashtable/SortedList and the Dictionary/SortedList Difference

If you use the System.Collections.Hashtable or the System.Collections.Generic.Dictionary class to create your list, the items are cumulatively added to the collection every time you call the Add() method or when you use the indexed property to add an item. In our introduction, we saw that the optional third rule of a dictionary type of list is that the list be sorted based on the key. To spare you the hassle of manually taking care of this, the alternative is to use the SortedList class.

Whenever a new item is added to a System.Collections.SortedList variable, a System.Collections.Generic.SortedDictionary variable, or a System.Collections.Generic.SortedList variable, the list is rearranged so the collection can be sorted in either alphabetical or chronological order based on the keys. This means that, if you want your list to be logically arranged by the keys, use one of these Sorted classes to create the collection.

The Keys and the Values of a Collection

After adding one or more items to the list, they are stored in two collections. The keys are stored in a collection represented by a property named Keys. The values are stored in the Values property. In the System.Collections classes, the Keys and the Values properties are of type ICollection.

To assist you with managing the keys of their collections, the System.Collections.Generic.Dictionary, the System.Collections.Generic.SortedDictionary, and the System.Collections.Generic.SortedList classes are equipped with a nested class named KeyCollection. KeyCollection is a serializable generic class that implements the ICollection<> interface. The only real functionalities of the nested KeyCollection class are its ability to know the current number of items in the list and the ability to enumerate the members of the collection through a foreach loop.

To assist you with the values of their lists, the System.Collections.Generic.Dictionary, the System.Collections.Generic.SortedDictionary, and the System.Collections.Generic.SortedList classes are equipped with the nested ValueCollection. The ValueCollection serializable class implements the ICollection<> and the IEnumerable interfaces. The functionality of the ValueCollection class is the same as its counterpart of the System.Collections namespace.

Checking the Existence of an Item

Locating an item in a dictionary type of list consists of looking for either a key, a value, or a combination of Key=Value. The Hashtable, the Dictionary, and the SortedList classes are equipped to handle these operations with little effort on your part. If you know the key of an item but want to find a value, you can use the indexed property because it produces it. Here is an example:

void StartForm(object sender, EventArgs e)
{
    Hashtable Students = new Hashtable();

    Students.Add("Hermine", "Tolston");
    Students.Add("Patrick", "Donley");
    Students.Add("Chrissie", "Hannovers");
    Students.Add("Patricia", "Herzog");
    Students["Michael"] = "Herlander";

    foreach (DictionaryEntry entry in Students)
        lbxStudents.Items.Add(entry.Key + " " + entry.Value);

    string Value = (string)Students["Chrissie"];
    MessageBox.Show("The value of the Chrissie key is " + Value);
}

This would produce:

To find out whether a Key/Value item exists in the list, if you are using one of the classes from the System.Collections namespace, you can call the System.Collections.Hashtable.Contains() or the System.Collections.SortedList.Contains() method. Its syntax is:

public virtual bool Contains(object key);

To look for an item, you pass its key as argument to this method. Here is an example:

void StartForm(object sender, EventArgs e)
{
    Hashtable Students = new Hashtable();

    Students.Add("Hermine", "Tolston");
    Students.Add("Patrick", "Donley");
    Students.Add("Chrissie", "Hannovers");
    Students.Add("Patricia", "Herzog");
    Students["Michael"] = "Herlander";

    foreach (DictionaryEntry entry in Students)
        lbxStudents.Items.Add(entry.Key + " " + entry.Value);

     bool found = Students.Contains("Chrissie");

    if (found == true)
        MessageBox.Show("The list contains an item " +
                        "whose key is Chrissie");
    else
        MessageBox.Show("The list doesn't contain an " +
                        "item whose key is Chrissie");

    found = Students.Contains("James");

    if (found == true)
        MessageBox.Show("The list contains an item " +
                        "whose key is James");
    else
        MessageBox.Show("The list doesn't contain an " +
                        "item whose key is James");
}

This would produce:

 

Checking the Existence of a Key

We have seen that the System.Collections.Hashtable.Contains() and the System.Collections.SortedList.Contains() methods allow you to find out whether a collection contains a certain specific key. An alternative is to call a method named ContainsKey.

The syntax of the System.Collections.Hashtable.ContainsKey() and the System.Collections.SortedList.ContainsKey() method is:

public virtual bool ContainsKey(object key);

The syntax of the System.Collections.Generic.Dictionary.ContainsKey() and the System.Collections.Generic.SortedList.ContainsKey() method is:

public bool ContainsKey(TKey key);

Checking the Existence of a Value

To find out whether a particular value exists in the list, you can call the ContainsValue() method. The syntax of the System.Collections.Hashtable.ContainsValue() and the System.Collections.SortedList.ContainsValue() method is::

public virtual bool ContainsValue(object key);

The syntax of the System.Collections.Generic.Dictionary.ContainsValue() and the System.Collections.Generic.SortedList.ContainsValue() method is:

public bool ContainsValue(TKey key);

Getting the Value of a Key

The ContainsKey() method allows you to only find out whether a dictionary-based collection contains a certain key. It does not identify that key and it does not give any significant information about that key, except its existence. In some operations, first you may want to find out if the collection contains a certain key. Second, if that key exists, you may want to get its corresponding value.

To assist you with both checking the existence of a key and getting its corresponding value, the generic Dictionary, SortedDictionary, and SortedList classes are equipped with a method named TryGetValue. Its syntax is:

public bool TryGetValue(TKey key, out TValue value);

When calling this method, the first argument must be the key to look for. If that key is found, the method returns its corresponding value as the second argument passed as an out reference.

Removing Items From a Dictionary Type of List

To delete one item from the list, you can call the Remove() method. Its syntax is:

public virtual void Remove(object key);

Here is an example:

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;

public class Exercise : Form
{
    ListBox lbxStudents;
    Button btnRemove;
    Hashtable Students;

    public Exercise()
    {
        InitializeComponent();
    }

    void InitializeComponent()
    {
        Text = "Students";
        lbxStudents = new ListBox();
        lbxStudents.Location = new Point(12, 12);
        Controls.Add(lbxStudents);

        btnRemove = new Button();
        btnRemove.Text = "&Remove";
        btnRemove.Location = 
        	new Point(12, lbxStudents.Top + lbxStudents.Height + 10);
        btnRemove.Click += new EventHandler(RemoverClick);
        Controls.Add(btnRemove);

        Load += new EventHandler(StartForm);
    }

    void StartForm(object sender, EventArgs e)
    {
        Students = new Hashtable();

        Students.Add("Hermine", "Tolston");
        Students.Add("Patrick", "Donley");
        Students.Add("Chrissie", "Hannovers");
        Students.Add("Patricia", "Herzog");
        Students["Michael"] = "Herlander";
        Students["Philemon"] = "Jacobs";
        Students["Antoinette"] = "Malhoun";

        foreach (DictionaryEntry entry in Students)
            lbxStudents.Items.Add(entry.Key + " " + entry.Value);
    }

    void RemoverClick(object sender, EventArgs e)
    {
        Students.Remove("Chrissie");

        lbxStudents.Items.Clear();
        foreach (DictionaryEntry entry in Students)
            lbxStudents.Items.Add(entry.Key + " " + entry.Value);
    }
}

This would produce:

To delete all items from the list, you can call the Clear() method. Its syntax is:

public virtual void Clear();
 

Home Copyright © 2010-2014, FunctionX