.netbackwards-compatibilitybinaryformatteriserializable

ISerializable and backward compatibility


I have to work an an old application that used binaryFormatter to serialize application data into filestream (say in a file named "data.oldformat") without any optimizazion the main class has been marked with attribute

<serializable()>public MainClass
....... 
end class

and the serialization code

dim b as new binaryformatter
b.serialize(mystream,mymainclass)

In an attempt to optimize the serialization/deserialization process I simply made the class implement the ISerializable interface and wrote some optimized serialization routines

<serializable()>public MainClass
       implements ISerializable
....... 
end class

The optimization works really well but I MUST find a way to reatrive the data inside the old files for backward compatibility.

How can I do that??

Pierluigi


Solution

  • stmax has an excellent answer, however I would implement it like this, which uses SerializationEntry.GetEnumerator() instead of try/catch. This way is cleaner and significantly faster.

    public MainClass(SerializationInfo info, StreamingContext context) {
        int version = 0;
        foreach (SerializationEntry s in info)
        {
            if (s.Name == "version") 
            {
                version = (int)s.Value;
                break;
            }
        }
    
        switch (version) {
          case 0:
            // deserialize "old format"
            break;
          case 1:
            // deserialize "new format, version 1"
            break;
          default:
            throw new NotSupportedException("version " + version + " is not supported.");
        }
    }
    

    I would prefer a LINQ version using .FirstOrDefault(), but SerializationInfo does not implement IEnumerable - in face, weirdly enough, it doesn't even implement the old IEnumerable interface.