2014-10-21 1 views
1

이전 버전의 응용 프로그램과 직렬화 된 일부 개체를 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로 역 직렬화하려고 :

나는 내가 여기에 붙여 넣습니다 짧은 자체에 포함 된 프로그램에 문제를 좁힐 수 있었다 목적. 두 개체는 완전히 같지만 프로그램은 ab 속성을 deserialize하지 않습니다. A = 0, B = 0, C = D (3) = 4

I 문제가 자동 등록 관련이있는 것으로 : 여기서

제가

얻고 출력한다. {get;set;}을 제거하고 필드로 변환하면 작동합니다. 하지만 내 응용 프로그램의 v1 개체는 속성이므로 작업해야합니다.

그럼 궁금한 점은 :이 비 직렬화를 제대로 작동 시키려면 어떻게해야합니까?

답변

1

비 직렬화 생성자를 제공하고 새 버전 유형에 대해 ISerializable을 구현해야합니다. 구버전 회원 헬퍼 클래스 SerializationHelper를 사용하여 SerializationInfo에서 액세스 할 수 있습니다

static class SerializationHelper 
{ 
    public static string GetAutoPropertyName(string baseTypeName, string name) 
    { 
     return baseTypeName + "+<" + name + ">k__BackingField"; 
    } 

    public static string GetAutoPropertyName(string name) 
    { 
     return "<" + name + ">k__BackingField"; 
    } 
} 

[Serializable] 
class v2base : ISerializable 
{ 
    protected v2base(
     SerializationInfo info, 
     StreamingContext context) 
    { 
     a = info.GetInt32(SerializationHelper.GetAutoPropertyName("v1base", "a")); 
     b = info.GetInt32(SerializationHelper.GetAutoPropertyName("v1base", "b")); 
    } 

    public int a { get; set; } 
    public int b { get; set; } 

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue(SerializationHelper.GetAutoPropertyName("v1base", "a"), a); 
     info.AddValue(SerializationHelper.GetAutoPropertyName("v1base", "b"), b); 
    } 
} 

[Serializable] 
class v2derived : v2base 
{ 
    protected v2derived(
     SerializationInfo info, 
     StreamingContext context) : base(info, context) 
    { 
     c = info.GetInt32(SerializationHelper.GetAutoPropertyName("c")); 
     d = info.GetInt32(SerializationHelper.GetAutoPropertyName("d")); 
    } 

    public int c { get; set; } 
    public int d { get; set; } 

    public override void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     base.GetObjectData(info, context); 
     info.AddValue(SerializationHelper.GetAutoPropertyName("c"), c); 
     info.AddValue(SerializationHelper.GetAutoPropertyName("c"), d); 
    } 
} 
+0

이 작동하는 것 같다,하지만'v1base'와'v1derived' 클래스를 수정하지 않고 그것을 할 수있는 방법이있다? 나는 낡은 객체를 옮기고 싶은 커다란 응용 프로그램에서이 작업을 수행해야하며 정의를 변경할 수는 없습니다. – Ove

+0

좀 더 파고 들었고'v1base'와'v1derived'를 수정하지 않고 값을 얻을 수있는 것처럼 보입니다. v2base 및 v2derived의 직렬화 생성자 내에서 호출을 다음과 같이 변경해야합니다. 'a = info.GetInt32 ("v1base + k__BackingField");'(b, c 및 d도 마찬가지 임) – Ove

+0

예, '지금 당장 똑같은 일을 했어. :) 흥미 롭다. 나는 결코 전에 –

관련 문제