Click here to Skip to main content
15,881,715 members
Articles / Programming Languages / Visual Basic

Serializable Generic Collection

Rate me:
Please Sign up or sign in to vote.
3.00/5 (6 votes)
27 Nov 2007CPOL 34.6K   217   22   1
A Generic collection that can be serialized in XML format.

Introduction

By default, Generic Collections can not be serialized using an XML serializer. I am trying to create a generic collection that can be serialized in XML format.

VB
Public Class CollectionBase(Of T)
        Inherits System.Collections.ObjectModel.Collection(Of T)
        Implements System.Xml.Serialization.IXmlSerializable

About this Collection

When we implement an XmlSerializable object, we must inherit it from IXmlSerializable. And then, we must implement three methods: GetSchema, ReadXml, WriteXml. In GetSchema, we must return a string that contains the XML schema about the object (we leave it blank in this version!). The ReadXml method will contain statements that deserialize the XML to objects, and finally in WriteXml, we serialize our collection into XML.

VB
Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) _
           Implements System.Xml.Serialization.IXmlSerializable.ReadXml
    Dim pc() As PropertyInfo = GetType(T).GetProperties()
    While reader.Read()
        If reader.Name = GetType(T).Name Then
            reader.Read()
            If pc.Length > 0 Then
                Dim ti As T = GetInstance()
                For i As Int32 = 0 To pc.Length - 1
                    If pc(i).CanRead And pc(i).CanWrite Then
                        Dim st As SerilalizeType = GetSerilalizeType(pc(i).PropertyType)
                        If st = SerilalizeType.Complex Then
                            Dim o As Object = GetInstance(pc(i).PropertyType)
                            DesrializeObject(reader, o, pc(i).Name)
                            pc(i).SetValue(ti, _
                                           Convert.ChangeType(o, pc(i).PropertyType), _
                                               Nothing)
                        ElseIf st = SerilalizeType.Guid Then
                            Dim strGuid As String = reader.ReadElementString(pc(i).Name)
                            Dim newId As Guid = New Guid(strGuid)
                            pc(i).SetValue(ti, New Guid(strGuid), Nothing)

                        ElseIf st = SerilalizeType.Array Then
    
                            Dim o As Object = Nothing
                            DesrializeArray(reader, o, pc(i).PropertyType)
                            pc(i).SetValue(ti, _
                                    Convert.ChangeType(o, pc(i).PropertyType), _
                                    Nothing)

                        ElseIf st = SerilalizeType.ICollection Then
                            Dim o As Object = Nothing
                            DesrializeCollection(reader, o, pc(i).PropertyType)
                            pc(i).SetValue(ti, _
                                   Convert.ChangeType(o, pc(i).PropertyType), _
                                       Nothing)
                        Else
                            pc(i).SetValue(ti, _
                            Convert.ChangeType( _
                            reader.ReadElementString(pc(i).Name), pc(i).PropertyType), _
                                Nothing)
                        End If
                    End If
                Next
                Me.Add(ti)
            End If
        End If
    End While
End Sub

Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) _
        Implements System.Xml.Serialization.IXmlSerializable.WriteXml
    Dim pc() As PropertyInfo = GetType(T).GetProperties()
    Dim ti As T = Nothing
    For i As Int32 = 0 To Me.Items.Count - 1
        ti = Me.Item(i)
        writer.WriteStartElement(GetType(T).Name)
        For j As Int32 = 0 To pc.Length - 1
            If pc(j).CanRead And pc(j).CanWrite Then
                writer.WriteStartElement(pc(j).Name)
                Dim st As SerilalizeType = GetSerilalizeType(pc(j).PropertyType)
                If st = SerilalizeType.Complex Or _
                   st = SerilalizeType.Array Or _
                   st = SerilalizeType.ICollection Then
                    writer.WriteRaw(SerializeObject(pc(j).GetValue(ti, Nothing)))
                Else
                    writer.WriteString(pc(j).GetValue(ti, Nothing).ToString())
                End If
                writer.WriteEndElement()
            End If
        Next
        writer.WriteEndElement()
    Next
End Sub

Using the Code

As is usual, here is how we use Generic Collections:

VB
Dim MyCol As New DNE.Components.CollectionBase(Of SomeObject)

I suggest inheriting your collection from this class. Our collection can now deserialize simple properties like string, integer, and arrays and objects that inherits from ICollection.

ToDo

Support serialization for Hashtables, Enums, and ....

History

  • Version 0.2: Support for Array and ICollection, fixed some bugs. 28/11/2007.
  • Version 0.1: Initial release. 11/11/2007.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Iran (Islamic Republic of) Iran (Islamic Republic of)
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralGeneric collections can be serialized using XmlSerializer Pin
Yingbiao13-Dec-09 18:28
Yingbiao13-Dec-09 18:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.