A strategy for deserializing a class that has changed in .NET.

I have this class

[Serializable] public class myClass() : ISerializable { public int a; public int b; public int c; public void GetObjectData(SerializationInfo info, StreamingContext context) { // Some code } public myClass(SerializationInfo info, StreamingContext context) { // Some code } } 

I have hundreds of these objects in my database. Now I am ready to publish a new version of my application, where the class has changed to

 [Serializable] public class myClass() : ISerializable { public int a; public string b; public int c; public bool d; public void GetObjectData(SerializationInfo info, StreamingContext context) { // Some code } public myClass(SerializationInfo info, StreamingContext context) { // Some code } } 

How to deserialize an object serialized based on the first version using the de-serialization constructor of the second.

Are there also strategies for a future version checking out my second version of the class?

+6
source share
2 answers

Without preparation on your part, you may need to hack: when your deserialization constructor public myClass gets the value bool d , public myClass code in try / catch and set d to the default when you encounter an exception.

In the future, add an int "__ver" value (or any other name that does not collide with the arguments that you pass to info.AddValue ) and set a constant for it that you support in your class to indicate compatible and incompatible serialization changes :

 public class myClass : ISerializable { private const int __ver = 4; public int a; public string b; public int c; public bool d; public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("__ver", ver); info.AddValue("a", a); // and so on } public myClass(SerializationInfo info, StreamingContext context) { switch(info.GetInt32("__ver")) { case 3: // Deserialize prior version break; case 4: // Deserialize current version break; } } } 
+4
source

Serializable classes are great for passing them through the same software version, but you quickly hit this issue when you use it to save. If you are going to store objects as BLOBs , then perhaps use something like protobuf-net , which allows serialization using additional fields.

Given your current predicament, all you can do to make it work imediatly is trying to catch the new fields, and then default them if they are not there:

 protected myClass(SerializationInfo info, StreamingContext context) { c = info.GetInt32("Value_C"); try { b = info.GetBoolean("Value_B"); } catch (SerializationException) { b = true; } } 
+2
source

Source: https://habr.com/ru/post/913662/


All Articles