protobuf-net:枚举类型转换错误

时间:2016-10-06 22:13:16

标签: c# serialization enums protocol-buffers protobuf-net

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

System.InvalidCastException:从'System.Int32'转换为无效的转换   'MyNamespace.MyEnum'。

1 个答案:

答案 0 :(得分:0)

我正在使用protobuf-net v2.1.0,根据方法,我得到两个不同的ProtoExceptionNo wire-value is mapped to the enum MyEnumNo parameterless constructor foundpublic enum MyEnum { EnumName1 = 1, EnumName2 = 2, @default = 0 } public MyClass() { MyEnumProperty = MyEnum.EnumName1 } 。原因是:默认的int值0不是枚举类型中的常量,或者您没有在参数构造函数中为其指定默认值。

解决方法(逻辑或):

#if !DEBUG
    protected void Application_Error(object sender, EventArgs e)
    {
        Exception exception = Server.GetLastError();
        // save exception inf to DB
        Server.ClearError();
        Response.Redirect("/Home/Error");
    }
#endif

<system.web>   
   <!--<customErrors mode="Off"></customErrors> -->
   <!-- or -->
   <customErrors mode="On">
     <error statusCode="404" redirect="~/Home/NotFound"/>
   </customErrors>
</system.web>

来自ECMA-334 C# Language Specification

  
      
  1. 未明确声明基础的枚举声明   type的底层类型为int。如果枚举成员是枚举类型中声明的第一个枚举成员,则其关联值为零。
  2.   
  3. 枚举用于“多选”场景,其中包含运行时   决定是从已知的固定数量的选择中做出的   编译时
  4.   

因此,具有运行时值的枚举(尚未定义为编译时常量imo)是一个糟糕的枚举。