当基础类稍微改变时,我可以反序列化对象吗?

时间:2011-05-10 11:41:16

标签: vb.net visual-studio-2010 serialization deserialization binaryformatter

我编写了一个自定义类MyClass,并使用<Serializable()>属性对其进行了标记。我的硬盘驱动器上有一组二进制文件,我使用来自BinaryFormatter实例的MyClass进行了序列化。

我最近稍微更改了MyClass的结构(添加了一些属性,删除了一些属性,更改了一些方法等)。

当我尝试使用下面的代码将现有对象反序列化为此更改的类时会发生什么?我已经尝试过并且没有抛出任何错误或其他任何东西 - 但肯定无法反序列化当班级改变了吗?有没有办法可以从序列化文件中获取一些有用的信息,即使我已经更新了这个类?

感谢。


这是我用来进行序列化的代码:

Public Sub serializeObject(ByVal obj As Object, ByVal outFilename As String)
    Dim fStream As FileStream
    Try
        fStream = New FileStream(outFilename, FileMode.Create)
        Dim bfmtr As New BinaryFormatter
        bfmtr.Serialize(fStream, obj)
        fStream.Close()
    Catch ex As Exception
        MsgBox("Failed to serialize: " & ex.Message)
        Throw
    End Try
End Sub

要进行我正在使用的反序列化:

myObj = CType(deserializeObject("C:\myobject.bin"), MyClass))

deserializeObject的位置:

Public Function deserializeObject(ByVal srcFilename As String) As Object
    If File.Exists(srcFilename) Then
        Dim fStream As Stream = File.OpenRead(srcFilename)
        Dim deserializer As New BinaryFormatter
        Dim returnObject As Object = deserializer.Deserialize(fStream)
        fStream.Close()
        Return returnObject
    Else
        Throw New ApplicationException("File not found: " & srcFilename)
    End If
End Function

4 个答案:

答案 0 :(得分:1)

过去我使用binaryformatter在序列化对象的微小变化之间存在兼容性问题,而且我也不完全理解为什么。有一种“UnsafeDeserialize”方法,它意味着更兼容的“反序列化”。

“发生的事情”是指当它确实存在兼容性破坏更改时,您根本无法重新创建该对象。我不知道是否有任何方法可以再次使用旧代码结构重新创建它。

我在这些情况下使用了XML序列化,这似乎更安全(并且可读,因此您可能会纠正以后出现的任何问题)

成本是在大多数情况下XML序列化对象的大小要大得多。压缩/解压缩可以帮助你。

以下是我用于此的XML例程。

''' <summary>
''' Serializes as object into XML format
''' This IS different then SOAP Serialization.
''' </summary>
''' <typeparam name="ObjectType">The type of the object being serialized</typeparam>
''' <param name="oObj">The object to serialize</param>
''' <returns>The XML Document (string) that is the serialized object in text form</returns>
Public Shared Function XmlSerialize(Of ObjectType)(ByVal oObj As Object) As String
    Dim sb As New System.Text.StringBuilder
    Dim sw As New IO.StringWriter(sb)
    Dim x As New System.Xml.Serialization.XmlSerializer(GetType(ObjectType))
    x.Serialize(sw, oObj)
    Return sb.ToString
End Function
''' <summary>
''' DeSerializes and object from an XML Document
''' This IS different then SOAP Serialization.
''' </summary>
''' <typeparam name="ObjectType">The Object type that will be returned (That the XML Data is derived from)</typeparam>
''' <param name="oObj">The Object (in it's XML Document serialized format)</param>
''' <returns>The new object</returns>
Public Shared Function XmlDeSerialize(Of ObjectType)(ByVal oObj As String) As ObjectType
    Dim sr As New IO.StringReader(oObj)
    Dim x As New System.Xml.Serialization.XmlSerializer(GetType(ObjectType))
    Dim out As ObjectType = CType(x.Deserialize(sr), ObjectType)
    Return out
End Function

答案 1 :(得分:1)

您需要控制序列化和反序列化过程。 您可以使用ISerializable界面执行此操作。

看看:

http://msdn.microsoft.com/en-us/library/ty01x675.aspx“实现ISerializable接口”部分中提供了一些有用的信息。

答案 2 :(得分:0)

添加和删除字段不应该有任何问题 - 我有经验证据,而不是我知道序列化在细节中是如何工作的。

更改私有属性的名称时可能会出现问题。所有其他的事情,甚至重新排序领域,你都很酷。

答案 3 :(得分:0)

我没有看过BinaryFormatter.Deserialize()的实际实现,所以我会推测。

我不认为反序列化器有责任确保类的所有属性都不为null。有很多场景,其中null属性是完全有效的,并且没有问题。

现在我可以回答你的问题:

我认为向类中添加属性不会导致问题,但我确实认为删除尝试反序列化的属性会导致错误。