2012-11-09 55 views
2

我試圖序列化一些類型安全枚舉,我實現了像the answer to this question。當我序列化一個包含引用的對象,比如FORMS(來自我鏈接的答案)時,我想在反序列化時將引用恢復爲靜態字段FORMS在C中的協議緩衝區和Typesafe枚舉#

我有一個解決方案,但它似乎有點蹩腳,因爲我不得不將它添加到包含typeafe枚舉的任何類。它非常簡單,只是使用回調來存儲和檢索枚舉的value領域:

public class SomethingContainingAnAuthenticationMethod 
    { 
     [ProtoMember(1)] 
     public int AuthenticationMethodDataTransferField { get; set; } 

     public AuthenticationMethod AuthenticationMethod { get; set; } 

     [ProtoBeforeSerialization] 
     public void PopulateDataTransferField() 
     { 
     AuthenticationMethodDataTransferField = AuthenticationMethod.value; 
     } 

     [ProtoAfterDeserialization] 
     public void PopulateAuthenticationMethodField() 
     { 
     AuthenticationMethod = AuthenticationMethod.FromInt(AuthenticationMethodDataTransferField); 
     } 
    } 

任何其他的想法,將不勝感激。

+0

您可以嘗試在類型安全的枚舉類上實現ISerializable。或者甚至可以更好地爲所有類型安全的枚舉類創建基類並在基類上實現ISerializable。當然,您應該將SerializableAttribute添加到每個類型安全的枚舉類。另外要注意的是平等測試。您需要值相等而不是引用相等(http://msdn.microsoft.com/en-us/library/dd183755.aspx)。 –

+0

K;你能澄清幾件事嗎?一個枚舉應該在沒有任何工作的情況下序列化好 - 如果你只是用ProtoMember標記枚舉成員會發生什麼?你試圖避免的症狀是什麼?另外:你提到「靜態字段」 - 你是否確實是指'靜態',如「特定於類型的,而不是實例特定的」?要麼...? –

+0

@Panos這個例子表明OP在談論protobuf-net,這些都不適用。 –

回答

2

,在鏈接例子答案,最簡單的方法可能是:

[ProtoContract] 
public class SomethingContainingAnAuthenticationMethod 
{ 
    [ProtoMember(1)] 
    private int? AuthenticationMethodDataTransferField { 
     get { return AuthenticationMethod == null ? (int?)null 
           : AuthenticationMethod.Value; } 
     set { AuthenticationMethod = value == null ? null 
           : AuthenticationMethod.FromInt(value.Value); } 
    } 

    public AuthenticationMethod AuthenticationMethod { get; set; } 
} 

它避免了額外的字段和任何回調。類似的東西也可以通過代理類型來完成,但上述應用適用於大多數簡單情況。

1

序列化枚舉成員的機制是非常簡單的:

[ProtoContract] 
public class SomethingContainingAnAuthenticationMethod 
{ 
    [ProtoMember(1)] 
    public AuthenticationMethod AuthenticationMethod { get; set; } 
} 

而且......僅此而已。次要疑難雜症有時(這可能會提高對未能找到值枚舉錯誤)是隱含的零的行爲,但是這僅僅是避免:

[ProtoMember(1, IsRequired=true)] 
    public AuthenticationMethod AuthenticationMethod { get; set; }