Я пытаюсь десериализовать некоторые объекты, которые были сериализованы со старой версией моего приложения, чтобы обновить их до нового формата, который я использую в новой версии приложения.Deserializing производные классы с пользовательским SerializationBinder
Для этого я использую пользовательский SerializationBinder для сопоставления старых объектов с новыми.
Я могу перенести большинство моих объектов таким образом, но у меня есть проблема, когда один из моих объектов получен из базового класса. Проблема в том, что свойства внутри базового класса не будут десериализованы (только свойства в производном классе будут десериализованы).
я был в состоянии сузить проблему в короткий самодостаточного программе, я буду вставить здесь:
namespace SerializationTest
{
class Program
{
static void Main(string[] args)
{
v1derived first = new v1derived() { a = 1, b = 2, c = 3, d = 4 };
v2derived second = null;
BinaryFormatter bf = new BinaryFormatter();
bf.Binder = new MyBinder();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, first);
ms.Seek(0, SeekOrigin.Begin);
second = (v2derived)bf.Deserialize(ms);
Console.WriteLine("a={0} b={1} c={2} d={3}", second.a, second.b, second.c, second.d);
}
}
class MyBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
if (typeName == "SerializationTest.v1base")
{
return typeof(v2base);
}
if (typeName == "SerializationTest.v1derived")
{
return typeof(v2derived);
}
return null;
}
}
[Serializable]
class v1base
{
public int a { get; set; }
public int b { get; set; }
}
[Serializable]
class v1derived : v1base
{
public int c { get; set; }
public int d { get; set; }
}
[Serializable]
class v2base
{
public int a { get; set; }
public int b { get; set; }
}
[Serializable]
class v2derived : v2base
{
public int c { get; set; }
public int d { get; set; }
}
}
В этой программе я сериализации v1derived объект, и пытается десериализации его как v2derived объект. Оба объекта абсолютно одинаковы, но программа не десериализует свойства a
и b
.
Вот выход я получаю: а = 0 Ь = 0 с = 3 d = 4
Я полагаю, что проблема связана с авто-свойств. Если я удалю {get;set;}
и превращу их в поля, то он будет работать. Но объекты v1 в моем приложении являются свойствами, поэтому я должен работать с этим.
Итак, вопрос: как я могу заставить эту десериализацию работать правильно?
Это, кажется, работает, но есть ли способ сделать это без изменения '' v1base' и классов v1derived'? Мне нужно сделать это в более крупном приложении, где я хочу перенести некоторые старые объекты, и я не могу изменить их определение. – Ove
Я сделал еще несколько копаний, и похоже, что вы можете получить значения без изменения 'v1base' и' v1derived'. Вам нужно изменить вызов внутри конструктора сериализации v2base и v2derived на что-то вроде этого, и он будет работать: 'a = info.GetInt32 (" v1base + k__BackingField ");' (то же самое для b, c и d) – Ove
Да, я Я сделал то же самое сейчас :) Интересно, я никогда не делал этого до –