开发者

Can I deserialize an object when the underlying class has been changed slightly?

I've written a custom class MyClass and marked it with the <Serializable()> attribute. I have a set of binary files on my hard drive that I've serialized using BinaryFormatter that came from instances of MyClass.

I've recently changed the structure of MyClass slightly (added some properties, deleted some properties, changed a few methods, etc).

What happens when I try to deserialize the existing objects to this changed class using the code below? I've tried it and not had an error thrown or anything - but surely it can't deserialize properly when the c开发者_Python百科lass has changed? Is there a way I can get some useful information out of the serialized files even though I've updated the class?

Thanks.


Here's the code I'm using to do the serialization:

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

And to do the deserialization I'm using:

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

Where deserializeObject is:

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


In the past I have had compatability issues between minor changes in serialized objects using the binaryformatter, and I also do not fully understand why. There is a "UnsafeDeserialize" method which sort of implies a more compatible "deserialize".

The "What Happens" is when it does have a compatibility breaking change, you simply cannot recreate the object. I don't know if there is any way to recreate it again short of using old code structure.

I have used XML serialization in these cases which seems to be much safer (and is readable so you could potentially correct any issue you have later)

The cost is that the size of the XML serialized objects is considerably larger in most cases. Compressing/decompressing can help that.

Here are my XML routines I use for this.

''' <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


You will need to control the serialization and deserialization process. You may use the ISerializable interface to do this.

Take a look at:

http://msdn.microsoft.com/en-us/library/ty01x675.aspx, there is some useful information in the section "Implementing the ISerializable Interface".


Adding and removing fields SHOULD NOT be of any problem - I have empirical proof of that, not that I know how the serialization works in the detail.

You could have problems when changing the name of the private properties. All other things, even reordering the fields, you're cool.


I haven't looked at the actual implementation of BinaryFormatter.Deserialize() so I will speculate.

I dont think that it is the responsibility of the deserializer to ensure that all the properties of a class are not null. There are plenty of scenarios where null properties are totally valid and cause no problems.

Now I can answer your question:

I believe that adding properties to a class will not cause problems however, I do think that removing properties that you are attempting to deserialize will cause errors.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜