2011-05-19 34 views
1

我有輕微特有節目與案件非常相似,這 交易(在C#的僞代碼):引用語義在谷歌協議緩衝

class CDataSet 
{ 
    int m_nID; 
    string m_sTag; 
    float m_fValue; 
    void PrintData() 
    { 
     //Blah Blah 
    } 
}; 

class CDataItem 
{ 
    int m_nID; 
    string m_sTag; 
    CDataSet m_refData; 
    CDataSet m_refParent; 
    void Print() 
    { 
     if(null == m_refData) 
     { 
     m_refParent.PrintData(); 
     } 
    else 
     { 
     m_refData.PrintData(); 
     } 
    } 
}; 

成員m_refData和m_refParent被初始化爲null,作爲如下: m_refData - >添加新數據集時使用 m_refParent - >用於指向現有數據集。 僅當字段m_nID與現有字段不匹配時,纔會添加新的數據集。

目前這段代碼管理着大約500個對象,每個對象大約有21個字段,截至目前爲止,選擇的格式是XML,它在100k +行和5MB +時非常笨拙。

我打算修改整個shebang使用ProtoBuf,但目前我不確定如何處理引用語義。任何想法將不勝感激

回答

1

開箱即用,協議緩衝區沒有任何引用語義。您需要手動交叉引用它們,通常使用人工鍵。基本上在DTO層上,你需要一個CDataSet的關鍵字(你可以簡單地發明一下,也許只是一個遞增的整數),將關鍵字存儲在m_refData/m_refParent中,並且在序列化/反序列化過程中手動運行fixup。您也可以將索引存儲到CDataSet集合中,但這可能會使插入等更加困難。由你決定;由於這是序列化,你可能會爭辯說,你不會在最初的人口之外插入(等),因此原始指數是可靠的。

然而,這是一個非常常見的場景 - 作爲特定於實現的功能,我添加了對我的實現(protobuf-net)的可選參數跟蹤(opt-in),該參數實際上自動化了上述(所以你不需要改變你的對象或在二進制流之外暴露密鑰)。