2017-05-15 4 views
1

Protobuf-net serializer로 몇 가지 테스트를하고 속성 직렬화를 실험하고있었습니다. 기본적으로 사전 (문자열, int)을 사전 (문자열, 문자열)으로 저장하고 deserialization에서 (문자열, 문자열)을 (문자열, int)로 다시 변환하려고합니다. 그러나, 놀랍게도 그것은 많은 것을 혼란스럽게했던 비 직렬화 (그리고 나서 null 참조 예외를 던짐)에 대한 TestDictionary의 getter를 통해 진행됩니다. 나는 그것이 비 직렬화에 관한 세터를 통과한다고 생각한다. 따라서 본질적으로 속성 직렬화가 어떻게 작동 하는지를 잘 모릅니다. 내가 작성한 간단한 테스트 클래스는 다음과 같습니다.Protobuf-net의 이해 직렬화 및 속성의 비 직렬화

[ProtoContract] 
public class Class1 
{ 
    [ProtoMember(2)] 
    public int test; 
    public Dictionary<string, int> testDictionary; 
    //public Dictionary<string, string> testDictionaryString; 
    [ProtoMember(3)] 
    private string test2; 
    [ProtoMember(4)] 
    private string test3; 
    [ProtoMember(5)] 
    private string test4; 

    public Class1() 
     {} 

    public Class1(int test) 
    { 
     this.test = test; 
      this.testDictionary = new Dictionary<string, int>(); 
     for (int i = 0; i < test; i++) 
     { 
      this.testDictionary.Add("a" + i.ToString(), i); 
     } 
     test2 = (test + 1).ToString(); 
     test3 = (test + 2).ToString(); 
     test4 = (test + 3).ToString(); 
    } 

    [ProtoMember(1)] 
    public Dictionary<string, string> TestDictionary 
    { 
     get 
     { 
      Dictionary<string, string> temp = new Dictionary<string, string>(); 
      foreach (KeyValuePair<string, int> pair in this.testDictionary) 
      { 
       temp.Add(pair.Key, pair.Value.ToString()); 
      } 
      return temp; 
     } 
     set 
     { 
      testDictionary = new Dictionary<string, int>(); 
      foreach (KeyValuePair<string, string> pair in value) 
      { 
       testDictionary.Add(pair.Key, Convert.ToInt32(pair.Value)); 
      } 
     } 
    } 
+0

탈 직렬화는 아마도 각 키/값 쌍에 대해'obj.TestDictionary [key] = value'와 같은 것을합니다 - 그것은 getter가 반환 한 사전을 변경합니다. 접근 방식은 사전을 먼저 비 직렬화 한 다음 그 결과를 속성에 할당 한 경우에만 작동합니다. –

+1

'int'를'string'보다 저장하는 것이 훨씬 저렴합니다. 따라서 실제 코드에서는 이것을하지 않을 것입니다. API를 실험하고 있다면 : 괜찮아요. –

답변

0

사전은 목록처럼 취급됩니다. 당신은 (A set 사용할 수 있다는 것을 가정)과 같은 같은 기본 목록 직렬화 상상할 수 :

var list = obj.TheProperty; 
if(list == null) { 
    list = new TheListType(); 
    obj.TheProperty = list; 
} 
do { 
    list.Add(DeserializeTheItemType(reader)); 
} while ({still that field}) 

그러나, 당신이 그것을 영향을 미칠 수 있습니다. 간단히 OverwriteTrue = true를 추가하면 사용자의 필요에 충분하다 :

var list = new TheListType(); 
do { 
    list.Add(DeserializeTheItemType(reader)); 
} while ({still that field}) 
obj.TheProperty = list; 

여기서 중요한 결과 그러나 Merge가 더 이상 일반적인 예상에 작동하지 않을 것입니다 : 이것은 이제 더 그런 짓을해야

[ProtoMember(1, OverwriteList = true)] 
public Dictionary<string, string> TestDictionary {...} 

방법. 보조 노트로

: 당신은 get/ set 아마 통해 null의를 통과해야하므로 그 testDictionarynull, TestDictionary 반환 null 인 경우; TestDictionary이면에서 null으로 설정하면 testDictionarynull으로 설정됩니다.

관련 문제