Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refactor a class that is serialized in .NET?

I have a C# class that is serialized to disk by the BinaryFormatter, such as this example:

// Version 3.0
[Serializable]
public class Person
{
    public string FullName;

    [OptionalField(VersionAdded=2)]
    public string NickName;
    [OptionalField(VersionAdded=2)]
    public DateTime BirthDate;

    [OptionalField(VersionAdded=3)]
    public int Weight;
}

Later, I want to refactor this class by one or more of the following
- Change its name
- Change its namespace
- Move to another assembly

As far as I can tell, the binary file can only be de-serialized if a class with the exact same name, namespace and assembly name is available.

How do I work around this?
Is it possible to map the de-serialization to a different class name, namespace and assembly without breaking Version Tolerant Serialization?

like image 438
angularsen Avatar asked Aug 23 '10 07:08

angularsen


People also ask

How do I prevent some data from getting serialized?

You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.

What is serializing a class?

To serialize an object means to convert its state to a byte stream so that the byte stream can be reverted back into a copy of the object. A Java object is serializable if its class or any of its superclasses implements either the java.

Can we store without serialized data into session?

Using InProc sessions, the data is not "stored" anywhere, it just stays in memory. This way no serialization is needed. For the other methods the data does need to be written to somewhere (state server, sql server) and needs to be converted to a stream of bytes (and back again).

Can a serializable class have methods?

Serializable in Java If you want a class object to be serializable, all you need to do it implement the java. io. Serializable interface. Serializable in java is a marker interface and has no fields or methods to implement.


2 Answers

After some research I realized that the BinaryFormatter does support everything I was looking for.

A BinaryFormatter can use surrogates to

  1. Provides the ability to serialize a type that was not originally designed to be serialized.
  2. Provides a way to map one version of a type to another version of another type.

One can also map deserialization from type A to type B (different class name, namespace and/or assembly name) by using SerializationBinder.

As far as I can tell, this makes it possible to refactor classes that are serialized and to maintain backwards compatibility when making breaking changes that is not supported by versioning alone.

Reference: http://www.diranieh.com/NETSerialization/BinarySerialization.htm

Edit: On a side note, refactoring fields (name or type) is still a pain, as discussed in Renaming fields then deserializing in C#. I am currently looking into protobuf-net to better solve this in the future.

like image 102
angularsen Avatar answered Oct 13 '22 22:10

angularsen


You can implement the ISerializable interface and override GetObjectData to provide your own deserialization. I have not tried, but you should be able to deserialize your old object "manually".

like image 29
Albin Sunnanbo Avatar answered Oct 13 '22 20:10

Albin Sunnanbo