简体   繁体   中英

Protocol Buffers and Typesafe Enums in C#

I'm trying to serialize some typesafe enums which I implemented likethe answer to this question . When I serialize an object containing a reference to, say, FORMS (from the answer I linked), I'd like, upon deserialization, to restore the reference to the static field FORMS .

I have a solution but it seems kind crappy since I'd have to add it to any class that contained a typesafe enum. It pretty much just uses callbacks to store and retrieve the enum's value field:

    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);
      }
    }

Any other ideas would be much appreciated.

With the answer in the linked example, the simplest approach is probably:

[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; }
}

which avoids an extra field and any callbacks. Something similar could also be done via a surrogate-type, but the above should work for most simple cases.

The mechanism for serializing an enum member is pretty simple:

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

And... that's about it. The minor gotcha sometimes (which might raise errors about not being able to find an enum with value) is the implicit-zero behaviour, but that is simply avoided:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM