Десериализация более новой версии объекта из более старой версии объекта
Предположим, у меня был этот класс:
[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()]
как объяснено в версии Tolerant Serialization
Затем класс будет выглядеть так:
[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 на поле, где поле имеет значение по умолчанию. IE.
public class SomeClass
{
public SomeClass() { }
int someInt = 10;
public string SomeString { get; set; }
public int SomeInt
{
get { return someInt; }
set { someInt = value; }
}
}
Затем, когда сериализатор десериализует объект, если значение SomeInt не предоставлено, значение по умолчанию все еще установлено.
РЕДАКТИРОВАТЬ: Обновление
Добавлен пример приложения с использованием 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
}