2012-11-09 25 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; }