Я пытаюсь десериализовать некоторые объекты, которые были сериализованы в старой версии моего приложения, чтобы обновить их до нового формата, который я использую в новой версии приложения.
Для этого я использую пользовательский 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; }
}
}
В этой программе я сериализую объект, производный от v1, и пытаюсь десериализовать его как объект, производный от v2. Оба объекта совершенно одинаковы, но программа не десериализует свойства a
и b
.
Вот что я получаю: a=0 b=0 c=3 d=4
Я предполагаю, что проблема связана с автосвойствами. Если убрать {get;set;}
и превратить их в поля, то работать будет. Но объекты версии 1 в моем приложении являются свойствами, поэтому мне приходится с ними работать.
Итак, вопрос: как я могу заставить эту десериализацию работать правильно?