Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error while using ProtoBuf-Net with flags enum

While using ProtoBuf-Net and serializing an enum property, where the enum is set to [FlagsAttribute], I received the following error message when serializing an enum value composed of multiple flags.

The error is: The value (MyEnum.MyValue) has no wire-representation for property MyProperty

Where MyEnum is:

[Flags]
public Enum MyEnum
{
    MyValue = 0,
    MyValue1 = 1,
    MyValue2 = 2,
    MyValue4 = 4,
    MyValue8 = 8,
}

and

MyProperty = MyEnum.MyValue2 | MyEnum.MyValue4;

Seems to be a bug in protobuf-net?

like image 771
Stécy Avatar asked Sep 29 '09 21:09

Stécy


People also ask

Does Protobuf support enum?

Protobuf supports enumeration types. You saw this support in the previous section, where an enum was used to determine the type of a Oneof field. You can define your own enumeration types, and Protobuf will compile them to C# enum types.

What is Protobuf net in C#?

protobuf-net is a contract based serializer for . NET code, that happens to write data in the "protocol buffers" serialization format engineered by Google.


1 Answers

Update : this is now fixed in r274; you would use:

[ProtoMember(12, DataFormat = DataFormat.TwosComplement)]
public MyEnum MyValue {get;set;}

Ultimately the protocol buffers wire format doesn't provide any scope for [Flags] enums - it enforces enum values against the discreet set. I could allow this easily enugh, but:

  • I'd probably have to disable enum mappings in this case, or do a lot of ugly bit- matching work
  • it would not be strictly compatible

An easier way of doing this may be to do a shim in your code:

public MyEnum MyValue {get;set;}
[ProtoMember(12)]
private int MyValueWire {
    get {return (int)MyValue;}
    set {MyValue = (MyEnum)value;}
}

The other alternative would be to add a flag that works like the above on your behalf; treating it as an int rather than an enum.

like image 160
Marc Gravell Avatar answered Oct 11 '22 11:10

Marc Gravell