Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleMake a generic serializable dictionary class and save and restore objects in it in Visual Basic 2005
DescriptionThis example shows how to make a generic serializable dictionary class and save and restore objects in it in Visual Basic 2005.
Keywordsserializable dictionary, Dictionary, serialization, serialize, generics, Visual Basic 2005, VB 2005
CategoriesSoftware Engineering
 
See Paul Welter's Weblog for the main ideas behind this example, although written in C#.

For some reason, Microsoft did not make the Dictionary class serializable. The SerializableDictionary class inherits from the Dictionary class. To provide serialization, it implements the ISerializable interface.

The WriteXml method takes an XmlWriter object as a parameter. It creates new XmlSerializer objects to serialize the generic data types used for the dictionary's keys and values. For each object stored in the dictionary, the code writes an "item" tag into the XmlWriter and then writes a "key" tag inside that. It uses the key serializer to save a serialization of the object's key amd uses WriteEndElement to close the "key" tag.

Next the routine uses the value serializer to save a serialization of the object's value amd uses WriteEndElement to close the "key" tag. It uses WriteEndElement again to close the "item" tag and then moves to the next item stored in the dictionary.

 
Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) _
    Implements _
    System.Xml.Serialization.IXmlSerializable.WriteXml
    Dim key_serializer As XmlSerializer = New _
        XmlSerializer(GetType(TKey))
    Dim value_serializer As XmlSerializer = New _
        XmlSerializer(GetType(TValue))
    For Each key As TKey In Me.Keys
        writer.WriteStartElement("item")
        writer.WriteStartElement("key")
        key_serializer.Serialize(writer, key)
        writer.WriteEndElement()
        writer.WriteStartElement("value")
        Dim value As TValue = Me.Item(key)
        value_serializer.Serialize(writer, value)
        writer.WriteEndElement()
        writer.WriteEndElement()
    Next key
End Sub
 

The ReadXml method reads data saved by subroutine WriteXml. It reads an "item" tag and the "key" tag that it contains. It reads the key serialization contained within the "key" tag and deserializes it. It then reads the "key" end tag.

The code repeats these steps to read the "value" tag, deserialize the value, and read the "value" end tag.

The routine then reads the "item" end tag and moves to the next element. The While loop ends when the code finds the next end element representing the end of the dictionary object.

 
Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) _
    Implements _
    System.Xml.Serialization.IXmlSerializable.ReadXml
    Dim key_serializer As New XmlSerializer(GetType(TKey))
    Dim value_serializer As New _
        XmlSerializer(GetType(TValue))

    Dim was_empty As Boolean = reader.IsEmptyElement
    reader.Read()
    If was_empty Then Exit Sub

    Do While reader.NodeType <> Xml.XmlNodeType.EndElement
        reader.ReadStartElement("item")
        reader.ReadStartElement("key")
        Dim key As TKey = _
            DirectCast(key_serializer.Deserialize(reader), _
            TKey)
        reader.ReadEndElement()
        reader.ReadStartElement("value")
        Dim value As TValue = _
            DirectCast(value_serializer.Deserialize(reader), _
            TValue)
        reader.ReadEndElement()
        Me.Add(key, value)
        reader.ReadEndElement()
        reader.MoveToContent()
    Loop

    reader.ReadEndElement()
End Sub
 
The example program makes a SerializableDictionary object that uses strings as keys and Person objects as values. It adds some data to the dictionary, serializes it into a string, and deserializes the result back into a dictionary. Then the program prints the serialization and the deserialized objects in the Command window.
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal _
    e As System.EventArgs) Handles MyBase.Load
    ' Make a SerializableDictionary.
    Dim dict As New SerializableDictionary(Of String, _
        Person)
    dict.Add("one", New Person("Ann", "Archer"))
    dict.Add("two", New Person("Bob", "Box"))
    dict.Add("three", New Person("Cindy", "Cant"))
    dict.Add("four", New Person("Dan", "Dive"))
    dict.Add("five", New Person("Edwina", "Eagle"))

    ' Show the serialization.
    Dim txt As String = ""
    Dim xml_serializer As New _
        XmlSerializer(GetType(SerializableDictionary(Of _
        String, Person)))
    Try
        Using string_writer As New StringWriter()
            xml_serializer.Serialize(string_writer, dict)
            txt = string_writer.ToString
            string_writer.Close()
        End Using
    Catch ex As Exception
        Stop
    End Try

    ' Deserialize.
    Using string_reader As New StringReader(txt)
        dict = DirectCast(xml_serializer.Deserialize(string_reader), _
            SerializableDictionary(Of String, Person))
    End Using

    txt &= vbCrLf & "***********" & vbCrLf
    For Each key As String In dict.Keys
        txt &= key & ": " & dict.Item(key).ToString() & _
            vbCrLf
    Next key

    txtResult.Text = txt
    txtResult.Select(0, 0)
End Sub
 
 
Copyright © 1997-2006 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated