이전 버전의 응용 프로그램과 직렬화 된 일부 개체를 deserialize하여 응용 프로그램의 새 버전에서 사용중인 새로운 형식으로 업그레이드하려고합니다.사용자 지정 SerializationBinder를 사용하여 파생 클래스를 deserializing
이렇게하려면 이전 객체를 새로운 객체에 매핑하기 위해 사용자 정의 SerializationBinder를 사용하고 있습니다.
이 방법으로 대부분의 개체를 마이그레이션 할 수 있지만 내 개체 중 하나가 기본 클래스에서 파생되면 문제가 발생합니다. 문제는 기본 클래스 내부의 속성이 deserialize되지 않는다는 것입니다 (파생 클래스의 속성 만 deserialize됩니다).
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
속성을 deserialize하지 않습니다. A = 0, B = 0, C = D (3) = 4
I 문제가 자동 등록 관련이있는 것으로 : 여기서
제가
얻고 출력한다.{get;set;}
을 제거하고 필드로 변환하면 작동합니다. 하지만 내 응용 프로그램의 v1 개체는 속성이므로 작업해야합니다.
그럼 궁금한 점은 :이 비 직렬화를 제대로 작동 시키려면 어떻게해야합니까?
이 작동하는 것 같다,하지만'v1base'와'v1derived' 클래스를 수정하지 않고 그것을 할 수있는 방법이있다? 나는 낡은 객체를 옮기고 싶은 커다란 응용 프로그램에서이 작업을 수행해야하며 정의를 변경할 수는 없습니다. – Ove
좀 더 파고 들었고'v1base'와'v1derived'를 수정하지 않고 값을 얻을 수있는 것처럼 보입니다. v2base 및 v2derived의 직렬화 생성자 내에서 호출을 다음과 같이 변경해야합니다. 'a = info.GetInt32 ("v1base + k__BackingField");'(b, c 및 d도 마찬가지 임) – Ove
예, '지금 당장 똑같은 일을 했어. :) 흥미 롭다. 나는 결코 전에 –