65.9K
CodeProject 正在变化。 阅读更多。
Home

可序列化的通用集合

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (6投票s)

2007年11月11日

CPOL
viewsIcon

35196

downloadIcon

250

一个可以以 XML 格式序列化的泛型集合。

引言

默认情况下,泛型集合无法使用 XML 序列化器进行序列化。我正在尝试创建一个可以以 XML 格式序列化的泛型集合。

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

关于这个集合

当我们实现一个 XmlSerializable 对象时,必须从 IXmlSerializable 继承它。然后,我们必须实现三个方法:GetSchemaReadXmlWriteXml。在 GetSchema 中,我们必须返回一个包含对象 XML 模式的字符串(在这个版本中我们将其留空!)。ReadXml 方法将包含将 XML 反序列化为对象的语句,最后在 WriteXml 中,我们将集合序列化为 XML。

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

像往常一样,以下是我们使用泛型集合的方式

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

我建议从这个类继承你的集合。我们的集合现在可以反序列化简单的属性,如字符串、整数和 数组 以及继承自 ICollection 的对象。

待办事项

支持 Hashtable、Enum 以及... 的序列化。

历史

  • 版本 0.2:支持 ArrayICollection,修复了一些错误。2007/11/28。
  • 版本 0.1:初始发布。2007/11/11。
© . All rights reserved.