2012-11-26 23 views
1

我試圖用Proto-buf替換我們現有的序列化。問題是我們目前使用ISerializable來檢查數據是否發生了變化,如果數據發生了變化,只能對原始值進行序列化。這是通過使用兩個可爲空的變量完成的,並且如果值已更改,則只將ISerializable.GetObjectData中的原始值添加到info對象。Protobuf-net - 序列化了什麼?

反序列化時,在ISerializable構造函數中,我讀取SerializationInfo來查找哪些成員被序列化,哪些成員不是。如果原始值未被序列化,則其值被設置爲當前值。 (因此節省資源,因爲它沒有序列化)。

有沒有在Protobuf網的方式來找出哪些字段被反序列化?我正在使用ShouldSerialize模式來發送原始值,但是當我到達另一端時,我需要知道哪些字段被序列化以能夠設置原始值。

編輯:更多詳情,這裏是一個樣本類。

[Serializable()] 
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)] 
public class SomeClass : ISerializable 
{ 
    internal int? _key; 
    internal int? _originalKey; 

    internal bool ShouldSerialize_key() 
    { 
     return _key.HasValue; 
    } 
    [NonSerialized] 
    public bool _keySpecified; 

    internal bool ShouldSerialize_originalKey() 
    { 
     return _key != _originalKey; 
    } 
    [NonSerialized] 
    public bool _originalKeySpecified; 
    [OnDeserialized()] 
    internal void OnDeserializedMethod(StreamingContext context) 
    { 
     // Use this to set the _originalKey if it hasn't been specified. 
     if (!_originalKeySpecified) 
     { 
      _originalKey = _key; 
     } 
    } 
} 

如您所見,如果_originalKey與_key具有相同的值,則不會對其進行序列化。當對象是反序列化時,我想知道_originalKey是否反序列化。我認爲你對_originalKeySpecified的回答會起作用,但是在上面的類中,一旦我反序列化,_originalKeySpecified總是錯誤的。 Protobuf反序列化過程是否確定了價值? (請注意,我不能使用ShouldSerialize屬性來決定是否在反序列化時設置_originalKey,因爲它可能已從null更改爲另一個值,我需要知道這些值何時保存在數據存儲中。

+0

重新編輯:請參閱我的答案中的措辭:「這是一個簡單的bool屬性...」 - 「_originalKeySpecified」是**不是** bool屬性,因此與它正在尋找的模式不匹配。請注意'_keySpecified'屬性。 –

+0

此外,請注意它不會使用** both **模式:它會查找'* Specified'屬性,然後查找'ShouldSerialize *'方法,然後停止。所以基本上你也可以把你的其他邏輯移到'* Specified'。這個順序是因爲'* Specified'允許'get'和'set'(分開); 'ShouldSerialize *'僅僅是一個'get',所以是第二選擇。 –

+0

啊* facepalm *。如下所述,它也必須公開。爲什麼它不能設置爲內部? –

回答

0

這取決於有點您的特定情況下,例如,如果您有可空後備字段,那麼:這是序列化的那些例子是具有非空值的那些...即

private int? id; 
[ProtoMember(n)] 
public int Id { 
    get { return id.GetValueOrDefault(); } 
    set { id = value; } 
} 
public bool ShouldSerializeId() { return id.HasValue; } 

在這裏,你可以簡單地檢查每個ShouldSerialize*方法來查看哪些值被反序列化;任何不是仍然會有null(它不會調用set如果它沒有要反序列化的數據)。

另一種方法是*Specified模式,如其他一些序列化器(XmlSerializer,IIRC - 和可能的DataContractSerializer)所使用的模式。這是一個簡單的布爾屬性,如果賦值,則被置1(由序列化程序)設置爲true,否則不會。同樣,*Specified的值與ShouldSerialize*的用法相同,以確定是否應在序列化期間處理成員。

如果我錯過了你的意圖,請澄清(最好用一個例子),我會試着解釋更多。

+0

我已經在上面添加了一些更多細節。 –