Десериализация более новой версии объекта из более старой версии объекта

Предположим, у меня был этот класс:

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

этот класс сериализуется при закрытии приложения и десериализуется при следующем запуске.

затем я построил его и выпустил приложение, и теперь класс изменился:

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

есть ли способ установить свойство по умолчанию при десериализации, если оно не найдено в старом сериализованном объекте?

один из способов, о котором я думал, - это сохранить старую версию класса, а затем проверить версия, которая была сериализована, затем зацикливает свойства старого объекта и устанавливает их в новом объекте, но это не имеет смысла для меня, любое другое решение, которое имеет смысл?

2 ответов


вы можете пометить поля атрибутом

[OptionalField()]

Как поясняется в Версия Сериализацию

класс будет выглядеть следующим образом:

[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;
    }
}

что я бы сделал, это основать SomeInt на поле, где поле имеет значение по умолчанию. ТО ЕСТЬ.

public class SomeClass
{
    public SomeClass() { }

    int someInt = 10;

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

затем, когда сериализатор десериализует объект, если значение SomeInt не указано, значение по умолчанию все еще установлено.

EDIT: Update

добавлен пример приложения с помощью XML-сериализатора. Теперь, чтобы переключить тип класса, просто раскомментируйте #define serialize оператор в строке 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
}