2014-07-21 4 views
1

다음 코드는 Protobuf-Net을 사용하여 List를 직렬화/비 직렬화하는 방법을 보여줍니다. 메서드 getNewItem()은 목록에 추가 된 ItemsStore의 개체를 반환합니다. 이 코드를 실행 한 후Protobuf-Net은 항상 비어있는 목록을 비 직렬화합니다.

// Create an empty list 
private ItemsStoreList text; 

// Add some elements to the list 
lock (text.SyncRoot) 
{ 
    text.AddItem(getNewItem()); 
    text.AddItem(getNewItem()); 
    text.AddItem(getNewItem()); 
} 

// Serialize 
var file = File.Create("testfile.bin"); 
Serializer.Serialize<ItemsStoreList>(file, text); 

// Deserialize 
ItemsStoreList textNew = Serializer.Deserialize<ItemsStoreList>(file); 

, 객체 textNew에 포함 된 목록은 항상 비어 있습니다. 객체 textNew은 다음과 같습니다 클래스 ItemsStoreList에서 인스턴스화 :

[ProtoContract] 
public class ItemsStoreList 
{ 
    [ProtoMember(1)] 
    private List<ItemsStore> m_listData; 

    private readonly object m_SyncRoot = new object(); 

    public ItemsStoreList() 
    { 
     m_listData = new List<ItemsStore>(); 
    } 

    public void AddItem(ItemsStore item) 
    { 
     m_listData.Add(item); 
    } 

    public object SyncRoot 
    { 
     get { return this.m_SyncRoot; } 
    } 

    public int Count 
    { 
     get { return m_listData.Count; } 
    } 

    public ItemsStore getItem(int idx) 
    { 
     return (ItemsStore)m_listData[idx]; 
    } 

    public void Clear() 
    { 
     m_listData.Clear(); 
    } 
} 

[ProtoContract] 
public class ItemsStore 
{ 
    [ProtoMember(1)] 
    public myStruct m_Text; 
    [ProtoMember(2)] 
    public ulong m_Time; 

    public ItemsStore(myStruct newText, ulong newTime) 
    { 
     m_Text = newText; 
     m_Time = newTime; 
    } 

    public myStruct Text 
    { 
     get { return m_Text; } 
    } 

    public ulong Time 
    { 
     get { return m_Time; } 
    } 
} 

[ProtoContract] 
public struct myStruct 
{ 
    [ProtoMember(1)] 
    public uint var1; 

    [ProtoMember(2)] 
    public byte var2; 

    [ProtoMember(3)] 
    public byte[] var3; 

    [ProtoMember(4)] 
    public string var4; 
} 
+0

다만, protobuf-net의 자동 튜플 처리 덕분에 생각할 수있는 것보다 "변경 가능한 구조체"가 실제로 생각보다 쉽게 ​​해결된다는 점에 유의하십시오. 유형에 proto 속성이 없지만 정확히 매개 변수가있는 생성자가있는 경우 public 멤버와 일치하면 생성자가 의도를 보여주는 것으로 가정합니다. 예 : http://pastie.org/9409395 –

답변

2

내가주의 첫 번째 것은 당신이 스트림을 되감기하지 않은 것입니다; (직렬화 및 역 직렬화 사이)이를 추가하면 동작 변경 :

file.Position = 0; 

우리는 이제 ItemsStore 생성자에 관한 예외가를, 그래서 우리는 완전히 그 생성자 무시 protobuf - 그물을 지시 할 수 있습니다 :

[ProtoContract(SkipConstructor = true)] 
public class ItemsStore 

을 이제 우리는 3 개 항목을 다시 얻을 : 출력되는

System.Console.WriteLine(textNew.Count); 

:

3 

또한 프로빙은 대부분 너무 다른 데이터를 가져 오는 것을 보여줍니다

for (int i = 0; i < textNew.Count; i++) 
{ 
    var item = textNew.getItem(i); 
    System.Console.WriteLine(item.m_Text.var1); 
    System.Console.WriteLine(item.m_Time); 
} 

나는, 그러나, 가변 구조체 및 공공 분야에 대한 의무적 인 경고를 추가합니다.