Welcome to Professional ASP.NET - Chris Love's Official Blog Sign in | Join | Help

Chris Love's Official ASP.NET Blog

Chris Love's Helpful tips, tricks and pragmatic development knowledge for the ASP.NET world.
Add to Technorati Favorites


ASP Insider
Chemistry and Dictionary(of TKey, TValue)

In college I majored in polymer chemistry and I thought I would use some of that chemistry today to demonstrate how to use Dictionary(of TKey, TValue) (VB.NET), Dictionary<TKey, TValue> (C#) class. The generic Dictionary(of TKey, TValue) class is a commonly used generic collection class that relies on a HashTable data structure to store keys and values, it is very fast and efficient.  The dictionary class implements both generic and non-generic IDictionary interfaces.

A generic Dictionary class works by accepting a key , and an object.  Keys can be any datatype, but I will be using a string for these examples. The key is used to retrieve the object after the collection has been built.  The object can be a value type or reference type such as a string, an integer or a custom object like an Atom class.

For these examples I created a class called Atom to represent an element on the periodic table.  This class is composed of several properties that define what an atom is.  I also took the time to override the ToString() method to return a custom string defining what the atom is.  To execute the examples I created a simple console application and added a few atoms to a periodic table Dictionary.

Public Class Atom

    Private _elementName As String
    Public Property ElementName() As String
        Get
            Return _elementName
        End Get
        Set(ByVal Value As String)
            _elementName = Value
        End Set
    End Property

    Private _symbol As String
    Public Property Symbol() As String
        Get
            Return _symbol
        End Get
        Set(ByVal Value As String)
            _symbol = Value
        End Set
    End Property

    Private _electrons As Integer
    Public Property Electrons() As Integer
        Get
            Return _electrons
        End Get
        Set(ByVal Value As Integer)
            _electrons = Value
        End Set
    End Property

    Private _protons As Integer
    Public Property Protons() As Integer
        Get
            Return _protons
        End Get
        Set(ByVal Value As Integer)
            _protons = Value
        End Set
    End Property
    
    Private _neutron As Integer
    Public Property Neutron() As Integer
        Get
            Return _neutron
        End Get
        Set(ByVal Value As Integer)
            _neutron = Value
        End Set
    End Property

    Public ReadOnly Property AtomicNumber() As Integer
        Get
            Return Protons
        End Get
    End Property

    Public ReadOnly Property MassNumber() As Integer
        Get
            Return Protons + Neutron
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return String.Format("{0} has an Atomic Number of {1} and a Symbol of {2}.", ElementName, AtomicNumber, Symbol)
    End Function

    Private _elementType As String
    ''' <summary>
    ''' Akali, Alkaline, Tansition, Halogen, Noble Gas, Lanthanide, Actinide
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property ElementType() As String
        Get
            Return _elementType
        End Get
        Set(ByVal Value As String)
            _elementType = Value
        End Set
    End Property

    Public Sub New(ByVal vElementName As String, ByVal vSymbol As String, ByVal vElectrons As Integer, _
        ByVal vProtons As Integer, ByVal vNeutrons As Integer, ByVal vElementType As String)

        ElementName = vElementName
        Symbol = vSymbol
        Electrons = vElectrons
        Protons = vProtons
        Neutron = vNeutrons
        ElementType = vElementType

    End Sub

End Class

The first example echoes the number of atoms, or objects, in the dictionary.  This is done with a console.WriteLine method call and the Dictionary’s count method.

Module Module1

    Sub Main()

        Dim periodicTable As New Dictionary(Of String, Atom)

        periodicTable.Add("H", New Atom("Hydrogen", "H", 1, 1, 0, "Alkali"))
        periodicTable.Add("C", New Atom("Carbon", "C", 6, 6, 6, "Metal"))
        periodicTable.Add("O", New Atom("Oxygen", "O", 8, 8, 8, "Metal"))

        Console.WriteLine(String.Format("There are {0} elements.", periodicTable.Count))
        Console.WriteLine("...")
        Console.ReadKey()

    End Sub

End Module

To add an atom to the dictionary call the add() method, passing the element’s symbol, such as “H”,  and a new Atom to object.  Notice I created the Atom’s using the custom constructor. I added hydrogen, carbon and oxygen to the dictionary, therefore there are three atoms in the dictionary.  The count method returns 3, which we see by executing the application.

In the next example we will see how to retrieve an object based on its key.  This is done by calling the ContainsKey() method, passing in the key assigned to the object.  If the key exist in the Dictionary, ContainsKey() returns true.  If the key does not exist and the Dictionary it returns false.

Console.WriteLine(String.Format("The Dictionary Contains does {0}Carbon.", _
            If(periodicTable.ContainsKey("C"), "", "not ")))
Console.WriteLine(String.Format("The Dictionary Contains does {0}Floride.", _
            If(periodicTable.ContainsKey("F"), "", "not ")))
Console.WriteLine("...")

We can also request a symbol to look up at the command line and pass it to the ContainsKey() method.  This opens up our little application to user input.

Console.WriteLine("Enter a Symbol to Lookup - ")
Dim ki As ConsoleKeyInfo = Console.ReadKey()

Console.WriteLine("")
Console.WriteLine(String.Format("The Dictionary Contains does {0}{1}.", _
            If(periodicTable.ContainsKey(ki.KeyChar), "", "not "), ki.KeyChar))
Console.WriteLine("...")

Finally, I want to show how to retrieve for the object from the dictionary.  To do this I will iterate over the dictionary with a for each loop.  In the foreach loop I will create a new element based on the KeyValuePair stored in the Dictionary.  The KeyValuePair has two properties of interest the key, and the value.  The value can be cast to and atom object.  Once we have an actual object we can call the ToString method to get a description of the Atom.

For Each element As KeyValuePair(Of String, Atom) In periodicTable
    Console.WriteLine(String.Format("{0} - {1}", element.Key, _
                DirectCast(element.Value, Atom).ToString))
Next

Console.WriteLine("...")
Console.ReadKey()

I hope these demonstrations give you a better idea of how to use the Dictionary(of TKey, TValue) class to store a list of items they can be easily retrieved by the key.  This class is extremely efficient for retrieving objects by key values, thus making searches easier than with a flat generic list class, List(of T).

Share this post :
Posted: Saturday, October 11, 2008 6:28 PM

by Chris Love
Filed under: , , ,

Comments

David Keaveny said:

Could you not use a KeyedCollection instead of a Dictionary? You then implement the GetKeyForItem(Atom atom) method protected override string GetKeyForItem(Atom atom) { return atom.Symbol; } Now your code becomes: periodicTable.Add(New Atom("Hydrogen", "H", 1, 1, 0, "Alkali")) periodicTable.Add(New Atom("Carbon", "C", 6, 6, 6, "Metal")) periodicTable.Add(New Atom("Oxygen", "O", 8, 8, 8, "Metal")) saving you the unnecessary duplication of the atomic symbol, while still allowing you to use indexers to retrieve the Atom by its symbol.
# October 12, 2008 8:48 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS