Десериализация более новой версии объекта из более старой версии объекта
Предположим, у меня был этот класс:
[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
}