Protobuf-net: enum类型转换错误

本文关键字:错误 类型转换 enum Protobuf-net | 更新日期: 2023-09-27 18:11:50

namespace MyNamespace                                               
{       
    public enum MyEnum
    {
        EnumName1 = 1,    
        EnumName2 = 2,
        ...
    [ProtoContract(Name=@"MyClassProto")]                                               
    [Serializable]                                                                                  
    public class MyClass : IExtensible                                              
    {                                                                                                                                           
        [ProtoMember(1, IsRequired = false, Name = @"MyEnumProperty", DataFormat = ProtoBuf.DataFormat.Default)]
        [System.ComponentModel.DefaultValue(1)]                                                     
        public MyEnum MyEnumProperty;                               
        ...

  var myObjectIn = new MyClass
  {
      MyEnumProperty = MyEnum.EnumName1,
      ...
  };
  MyClass myObjectOut;
  using (var stream = new MemoryStream())
  {
      ProtoBuf.Serializer.Serialize(stream, myObjectIn);
      stream.Seek(0, SeekOrigin.Begin);
      myObjectOut = ProtoBuf.Serializer.Deserialize<MyClass>(stream);
  }

系统。InvalidCastException:来自System的无效强制转换。Int32"MyNamespace.MyEnum"。

Protobuf-net: enum类型转换错误

我使用的是protobuf-net v2.1.0,根据不同的方法,我得到了两个不同的ProtoException。要么是No wire-value is mapped to the enum MyEnum,要么是No parameterless constructor found。原因是:默认的int值0在enum类型中不是常量,或者没有在形参构造函数中为其分配默认值。

解决方法(逻辑或):

public enum MyEnum { EnumName1 = 1, EnumName2 = 2, @default = 0 }

public MyClass() { MyEnumProperty = MyEnum.EnumName1 }

来自ECMA-334 c#语言规范

  1. 没有显式声明底层的枚举声明Type的基础类型是int。如果枚举成员是枚举类型中声明的第一个枚举成员,则其关联值为0。
  2. 枚举用于"多项选择"场景,其中运行时决策是由已知的固定数量的选择做出的编译时

所以,你的枚举没有定义为编译时常量的运行时值,在我看来,这是一个糟糕的枚举。