灵活序列化的任何想法

时间:2012-07-05 12:59:56

标签: .net serialization datacontract serializable

我有一些序列化输出的对象。对象的某些属性很难计算,需要一些时间来完成。我正在考虑的是如何指定用户想要获取的属性集,并仅序列化该集合而不是所有集合。

我已经做了一些研究,很清楚如何仅为标记为[Serializable]属性的对象序列化所需的属性,但在我的情况下,用[DataContract]标记的对象仍然有一些问题。

现在另一个问题是指定应该序列化的属性集。理想情况下,有一些像XQuery这样的东西可以指定应该序列化的内容。

所以,现在它的问题多于答案......任何想法/想法//建议不仅仅是欢迎!

1 个答案:

答案 0 :(得分:1)

以下示例创建一个简单的建筑,每层有3层楼和4个房间。这不是一个过于复杂的对象图,但我认为它应该得到这个想法。我们的想法是您可以实现System.Runtime.Serialization.ISerializable来控制序列化过程。

在这个例子中,我只为Floors类型实现了System.Runtime.Serialization.ISerializable。在Floors类型中,我控制Rooms列表的序列化和反序列化。

在不了解您的类型的具体细节的情况下,特别是计算量很大的属性,我不能具体说出来;但是,我认为通过使用实现System.Runtime.Serialization.ISerializable提供的技术并控制序列化过程,您将能够实现您正在寻找的结果。

请记住,您可以向序列化流添加任何内容,并且不需要在类中添加所有内容;但是,在反序列化构造函数运行后,您将希望至少使您的类“正确”。您放入序列化流的内容取决于您。

但请注意,这仅适用于二进制序列化,不适用于 Xml序列化

    Module Module1

    Sub Main()
        Dim floor1 As New Floor()
        floor1.Rooms.Add(New Rooms(101))
        floor1.Rooms.Add(New Rooms(102))
        floor1.Rooms.Add(New Rooms(103))
        floor1.Rooms.Add(New Rooms(104))

        Dim floor2 As New Floor()
        floor2.Rooms.Add(New Rooms(201))
        floor2.Rooms.Add(New Rooms(202))
        floor2.Rooms.Add(New Rooms(203))
        floor2.Rooms.Add(New Rooms(204))

        Dim floor3 As New Floor()
        floor3.Rooms.Add(New Rooms(301))
        floor3.Rooms.Add(New Rooms(302))
        floor3.Rooms.Add(New Rooms(303))
        floor3.Rooms.Add(New Rooms(304))

        Dim tower As New Building()
        tower.Floors.Add(floor1)
        tower.Floors.Add(floor2)
        tower.Floors.Add(floor3)

        Dim byteArray As Byte() = Serialized(tower)
        Dim backAgain As Building = DeSerialized(byteArray)
    End Sub

    Private Function Serialized(ByVal tower As Building) As Byte()
        Using ms As New System.IO.MemoryStream()
            Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            formatter.Serialize(ms, tower)
            Return ms.GetBuffer()
        End Using
    End Function

    Private Function DeSerialized(ByVal byteArray As Byte()) As Building
        Using ms As New System.IO.MemoryStream(byteArray)
            Dim formatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
            ms.Position = 0
            Return DirectCast(formatter.Deserialize(ms), Building)
        End Using
    End Function
End Module

<Serializable()>
Public Class Building
    Public Sub New()
    End Sub

    Private _Floors As New List(Of Floor)
    Public ReadOnly Property Floors As List(Of Floor)
        Get
            Return _Floors
        End Get
    End Property
End Class

<Serializable()>
Public Class Floor
    Implements System.Runtime.Serialization.ISerializable

    Public Sub New()
    End Sub

    Public Sub New(ByVal info As Runtime.Serialization.SerializationInfo, ByVal context As Runtime.Serialization.StreamingContext)
        Dim counter As Integer = info.GetInt32("RoomCount")
        For index As Integer = 0 To counter - 1
            _Rooms.Add(DirectCast(info.GetValue(String.Format("Room{0}", index.ToString()), GetType(Rooms)), Rooms))
        Next
    End Sub

    Private _Rooms As New List(Of Rooms)
    Public ReadOnly Property Rooms As List(Of Rooms)
        Get
            Return _Rooms
        End Get
    End Property

    Public Sub GetObjectData(info As System.Runtime.Serialization.SerializationInfo, context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData
        info.AddValue("RoomCount", _Rooms.Count)
        For index As Integer = 0 To _Rooms.Count - 1
            info.AddValue(String.Format("Room{0}", index.ToString()), _Rooms(index))
        Next
    End Sub
End Class

<Serializable()>
Public Class Rooms
    Public Sub New()
    End Sub

    Public Sub New(ByVal roomNum As Integer)
        Me.New()
        _RoomNumber = roomNum
    End Sub

    Private _RoomNumber As Integer = 0
    Public Readonly Property RoomNumber As Integer
        Get
            Return _RoomNumber
        End Get
    End Property
End Class