2009-05-30 5 views
7

필자는이 새로운 멤버가없는 이전 버전의 버전을 deserialize 할 때 [OptionalField] 특성을 사용하여 새 클래스의 새 멤버에 새 멤버를 추가해야합니다.[OptionalField] 속성은 무엇입니까?

그러나 InnerTranslator 속성이 클래스를 serialize 한 후에 추가 된 동안 아래 코드는 예외를 throw하지 않습니다. onDeserialization 메서드에서 (그것이 직렬화되지 않았 음을 확인하는) null이 될 속성을 확인합니다. 그러나 예외로 인해 예외가 throw 될 것으로 예상됩니다. [OptionalField] 특성 자체는 선택 사항입니까? 당신이 일을 변경하는 경우

class Program 
{ 
    static void Main(string[] args) 
    { 
     var listcol = new SortedList<string,string> 
     { 
      {"Estados Unidos", "United States"}, 
      {"Canadá", "Canada"}, 
      {"España", "Spain"} 
     }; 
     var translator = new CountryTranslator(listcol); 
     using (var file_stream=new FileStream("translator.bin",FileMode.Open)) 
     { 
      var formatter = new BinaryFormatter(); 
      translator = formatter.Deserialize(file_stream) as CountryTranslator; 
      file_stream.Close(); 
     } 
     Console.ReadLine(); 
    } 
} 

[Serializable] 
internal class CountryTranslator:IDeserializationCallback 
{ 
    public int Count { get; set; } 

    public CountryTranslator(SortedList<string,string> sorted_list) 
    { 
     this.country_list = sorted_list; 
     inner_translator = new List<string> {"one", "two"}; 
    } 
    //[OptionalField] 
    private List<string> inner_translator; 
    public List<string> InnerTranslator 
    { 
     get { return inner_translator; } 
     set { inner_translator = value; } 
    } 

    private SortedList<string, string> country_list; 

    public void OnDeserialization(object sender) 
    { 
     Debug.Assert(inner_translator == null); 
     Count=country_list.Count; 
    } 
} 
+0

inner_translator가 [OptionalField] 속성으로 장식되어 있지 않을 때 SOAP 포맷터가 예외를 throw한다는 것을 알게되었습니다. – Dabblernl

답변

8

BinaryFormatter은, 시대의 최고의에 매우 취약하다. 적어도 automatically implemented properties, obfuscaction에는 큰 문제가 있습니다. 이름 바꾸기, 강력한 이름 지정 등이 있습니다.

기억하기 바란다는 것은 이전에 릴리스 된 [OptionalField]에 대한 일부 규칙이 변경된 것입니다. 버전 관대 한 것은 실제로 계획대로 쉽게 작동하지 않았습니다.

조언 : 버전 관용 직렬화 (예 : 오늘 직렬화하고 다음 버전의 앱에서 비 직렬화 할 수 있음)를 원하면 BinaryFormatter을 사용하지 마십시오. 이것은 (IMO) 버전 (remoting, AppDomain 등) 사이의 데이터를 전달하는 데만 적합합니다.

버전 간 작업을 위해 계약 기반의 직렬화를 권장합니다. XmlSerializerDataContractSerializer (.NET 3.0) 또는 바이너리 -protobuf-net 또는 유사한 도구와 같은 것들. 이것들은 모두 버전 내결함성이 더 좋습니다 (실제로는 동일한 것으로 역 직렬화 할 필요조차 없습니다) Type); 플러스 그들은 플랫폼 사이에서 사용할 수 있습니다 - 그래서 당신은 .NET에서 직렬화하고 자바/C + +/등 deserialize 수 있습니다.

+0

정확하지 않은 대답을 찾았지만 DataContractSerializer를 독점적으로 사용한 것으로 나타났습니다. 당신은이 게시물에서 그것을 sugeested. 결국 고마워 ;-) – Dabblernl

+0

부울 값 또는 정수와 같은 값 유형에는 [OptionalField]를 사용 하시겠습니까? 또는이 속성은 OP의 질문과 같은 참조 유형에만 관련이 있습니까? –