在编程中,序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。反序列化则是将这种形式恢复为对象的过程。本文将介绍如何在VB.NET中使用集合进行数据的序列化和反序列化,包括处理未知的派生类型。
在VB.NET中,可以通过使用集合(Collections)而不是数组(Arrays)来实现序列化,这样可以提供更好的类型检查。集合可以包含不同类型的对象,这使得它们在处理复杂数据结构时非常有用。
本文不会展示所有的代码,但会提供基本的结构。可以下载应用程序以获取对象使用方式的演示。
在VB.NET中,定义了一个名为Citem的抽象类,它包含了基本的属性和方法。这个类是所有派生类型的基类。
Option Explicit On
Option Strict On
Imports System.Xml.Serialization
' 所有派生类型都需要在Citem类中使用XmlInclude属性进行声明
Public Class Citem
Private m_Id As Integer
Private m_Data As String
Public Property Id() As Integer
Get
Return m_Id
End Get
Set(ByVal value As Integer)
m_Id = value
End Set
End Property
Public Property Data() As String
Get
Return m_Data
End Get
Set(ByVal value As String)
m_Data = value
End Set
End Property
End Class
XItem类是Citem的一个派生类,它增加了一个额外的属性,用于演示XML输出的差异。
Option Explicit On
Option Strict On
Public Class XItem
Inherits Citem
Private m_D As Double
Public Property D() As Double
Get
Return m_D
End Get
Set(ByVal value As Double)
m_D = Value
End Set
End Property
End Class
YItem类是Citem的另一个派生类,它没有额外的属性。
Option Explicit On
Option Strict On
Public Class YItem
Inherits Citem
End Class
EItem类是Citem的另一个派生类,它包含了一个名为B的属性。注意,这个类没有在Citem类中使用XmlInclude属性声明,这是为了演示如何序列化/反序列化未知的派生类型。
Option Explicit On
Option Strict On
Public Class EItem
Inherits Citem
Private m_B As Double
Public Property B() As Double
Get
Return m_B
End Get
Set(ByVal value As Double)
m_B = value
End Set
End Property
End Class
Option Explicit On
Option Strict On
Imports System.Xml
Imports System.IO
Public Class MyCollection
Inherits System.Collections.CollectionBase
Public Overridable Function Add(ByVal value As Citem) As Integer
MyBase.List.Add(value)
End Function
Public Overridable Default Property Item(ByVal index As Integer) As Citem
Get
Return DirectCast(MyBase.List.Item(index), Citem)
End Get
Set(ByVal value As Citem)
MyBase.List.Item(index) = value
End Set
End Property
Public Shared Sub SerializeObject(ByVal filename As String, ByVal col As MyCollection, ByVal ExtraTypes() As System.Type)
Try
Dim s As New Xml.Serialization.XmlSerializer(GetType(MyCollection), ExtraTypes)
Dim writer As New StreamWriter(filename)
s.Serialize(writer, col)
writer.Close()
Catch x As System.InvalidOperationException
Throw New Exception("Check class Citem, all derived classes must be listed with the [XmlInclude(GetType(derivedClass))] attribute!")
End Try
End Sub
Public Shared Sub SerializeObject(ByVal filename As String, ByVal col As MyCollection)
Try
Dim s As New Xml.Serialization.XmlSerializer(GetType(MyCollection))
Dim writer As New StreamWriter(filename)
s.Serialize(writer, col)
writer.Close()
Catch x As System.InvalidOperationException
Throw New Exception("Check class Citem, all derived classes must be listed with the [XmlInclude(GetType(derivedClass))] attribute!")
End Try
End Sub
Public Shared Function DeserializeObject(ByVal filename As String, ByVal ExtraTypes() As System.Type) As MyCollection
Try
Dim fs As New IO.FileStream(filename, FileMode.Open)
Dim w As New Xml.Serialization.XmlSerializer(GetType(MyCollection), ExtraTypes)
Dim g As MyCollection = CType(w.Deserialize(fs), MyCollection)
fs.Close()
Return g
Catch x As Exception
Throw
End Try
End Function
Public Shared Function DeserializeObject(ByVal filename As String) As MyCollection
Try
Dim fs As New IO.FileStream(filename, FileMode.Open)
Dim w As New Xml.Serialization.XmlSerializer(GetType(MyCollection))
Dim g As MyCollection = CType(w.Deserialize(fs), MyCollection)
fs.Close()
Return g
Catch x As Exception
Throw
End Try
End Function
End Class