Deserializing a newer version of an object from an older version of the object

谁都会走 提交于 2019-12-04 12:16:26

问题


Suppose I had this class:

[Serializable]
public class SomeClass 
{
   public SomeClass() {//init}
   public string SomeString {get;set;}
}

This class gets Serialized when the application closes, and gets deserialized on the next run.

Then, I built it and released the application, and now the class has changed:

[Serializable]
public class SomeClass
{
   public SomeClass() {//init}
   public string SomeString {get;set;}
   public int SomeInt {get;set;}
}

Is there a way to set a property to its default on deserialization in case its not found in the old serialized object?

One way I thought about is keeping the old version of the class, then check the version that was serialized then looping properties of the old object and setting them in the new object, but this is non sense to me, any other solution that makes sense?


回答1:


You can mark fields with the attribute

[OptionalField()]

as explained in Version Tolerant Serialization

The class would then look like this:

[Serializable()]
public class SomeClass
{
    public SomeClass() {//init}
    public string SomeString { get; set; }

    [OptionalField(VersionAdded = 2)]
    public int SomeInt { get; set; }


    [OnDeserialized()]
    private void SetValuesOnDeserialized(StreamingContext context)
    {
        this.SomeInt = 10;
    }
}



回答2:


What i would do is base the SomeInt on a field where the field has a default value. IE.

public class SomeClass
{
    public SomeClass() { }

    int someInt = 10;

    public string SomeString { get; set; }
    public int SomeInt
    {
        get { return someInt; }
        set { someInt = value; }
    }
}

Then when the serializer deserializes the object if the SomeInt value is not provided the default value is still set.

EDIT: Update

Added a sample app using the XML serializer. Now to toggle the class type simply uncomment the #define serialize statement in row 2.

//uncomment for serialization
//#define serialize

using System;
using System.IO;
using System.Xml.Serialization;

namespace TestSerializer
{
    class Program
    {
        static void Main(string[] args)
        {

#if serialize

            SomeClass some = new SomeClass();
            some.SomeString = "abc";

            XmlSerializer serializer = new XmlSerializer(some.GetType());
            using (StringWriter writer = new StringWriter())
            {
                serializer.Serialize(writer, some);
                File.WriteAllText("D:\\test.xml", writer.ToString());
            }
#else
            XmlSerializer serializer = new XmlSerializer(typeof(SomeClass));
            using (StringReader reader = new StringReader(File.ReadAllText("D:\\test.xml")))
            {
                var o = serializer.Deserialize(reader) as SomeClass;
                if (o != null)
                    Console.WriteLine(o.SomeInt);
            }
            Console.ReadKey();
#endif
        }
    }



#if serialize

    [Serializable]
    public class SomeClass
    {
        public SomeClass() { }
        public string SomeString { get; set; }
    }
#else

    [Serializable]
    public class SomeClass
    {
        public SomeClass() { }
        private int someInt = 10;


        public string SomeString { get; set; }
        public int SomeInt
        {
            get { return someInt; }
            set { someInt = value; }
        }
    }
#endif
}


来源:https://stackoverflow.com/questions/19718306/deserializing-a-newer-version-of-an-object-from-an-older-version-of-the-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!