C#允许为枚举指定任何整数值。
当我尝试使用enum字段序列化(通过protobuf-net)对象时,该值超出范围,它会抛出异常:没有将wire-value映射到枚举PersonLevel。
我的枚举PersonLevel没有Flags属性。
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public enum PersonLevel
{
Unknown = 1
}
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class Person
{
...
public PersonLevel PersonLevel { get; set; }
...
}
var ms = new MemoryStream();
var person = new Person
{
...
PersonLevel = (PersonLevel) 500
...
};
Serializer.Serialize(ms, person); //No wire-value is mapped to the enum PersonLevel
在没有更改业务对象(可能是任何protobuf attrubutes)的情况下,是否有任何设施可以做到?
答案 0 :(得分:6)
有几种方法可以告诉它简化规则;正如Ravadre所说,[Flags]
会自动禁用验证 - 它会导致EnumPassthru
切换。您也可以手动执行此操作 - 只要之前开始序列化/反序列化:
RuntimeTypeModel.Default[typeof(PersonLevel)].EnumPassthru = true;
具有以下描述:
/// <summary>
/// Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather
/// than enforcing .proto enum rules. This is useful *in particular* for [Flags] enums.
/// </summary>
答案 1 :(得分:2)
你可以做的是创建一个int
字段,你将打包到protobuf消息中并公开一个属性,这将使你的int
字段显示为你的enum
类型包装)。
如果您使用隐式字段,这可能会更难,因为protobuf可能会尝试序列化您的整数和enum
属性。您可以尝试明确[ProtoIgnore]
您的enum
财产。
但是,如果您的枚举标记为[Flags]
属性,则protobuf会自动为您执行此操作,因此将您的枚举更改为:
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
[Flags]
public enum PersonLevel
{
Unknown = 1
}
应该让它发挥作用。至少在版本2中。