protobuf-net序列化System.Enum属性报错,如何自动转int实现序列化?
protobuf-net序列化System.Enum类型报错解决方案
报错原因
protobuf-net默认仅支持具体枚举类型的序列化逻辑,未提供抽象类型System.Enum的内置序列化实现,因此无法直接序列化基类中定义的Enum类型属性,抛出对应异常。
方案1:调整基类为泛型实现(推荐)
该方案无需修改序列化框架配置,同时保证类型安全,适配当前的类继承结构,修改后代码如下:
[ProtoContract] [ProtoInclude(101, typeof(SomeDerived))] [ProtoInclude(102, typeof(AnotherDerived))] // 增加泛型约束,限制为枚举类型 public abstract class Base<TEnum> where TEnum : Enum { protected Base() {} public Base(double doubleProp, TEnum enumProp) { DoubleProp = doubleProp; EnumProp = enumProp; } [ProtoMember(1)] public double DoubleProp { get; } [ProtoMember(2)] // 替换System.Enum为具体泛型枚举类型 public TEnum EnumProp { get; } // 其余逻辑保持不变 } public enum SomeDerivedEnum { // 枚举值保持不变 } public enum AnotherDerivedEnum { // 枚举值保持不变 } // 派生类继承时指定对应的具体枚举类型 public class SomeDerived : Base<SomeDerivedEnum> { private SomeDerived () : base() {} public SomeDerived (double doubleProp, SomeDerivedEnum someEnum) : base(doubleProp, someEnum) { } // 其余逻辑保持不变 } public class AnotherDerived : Base<AnotherDerivedEnum> { private AnotherDerived () : base() {} public AnotherDerived (double doubleProp, AnotherDerivedEnum anotherEnum) : base(doubleProp, anotherEnum) { } // 其余逻辑保持不变 }
修改完成后protobuf-net可以自动识别每个派生类对应的具体枚举类型,默认将其转换为int完成序列化、反序列化操作。
方案2:注册全局序列化规则(无需修改现有业务代码)
如果你不希望调整现有类的结构,可以在程序启动阶段为protobuf-net全局注册System.Enum的序列化/反序列化逻辑,实现自动转int处理:
// 程序初始化时执行一次即可 RuntimeTypeModel.Default.Add(typeof(Enum), false) .SetSerializer( // 序列化逻辑:将枚举转换为int写入 (ProtoWriter writer, Enum value) => writer.WriteInt32((int)(object)value), // 反序列化逻辑:读取int后转换为对应枚举值 (ProtoReader reader) => (Enum)(object)reader.ReadInt32() );
注意:该方案默认枚举底层类型为int,如果你使用了其他底层类型(如long)的枚举,需要对应调整读写逻辑的类型。
内容的提问来源于stack exchange,提问作者Rodrigo Martins
相关产品推荐
相关产品推荐

