在protobuf-net中,您可以使用ProtoEnumAttribute
覆盖枚举的有线格式,如下所示:
[ProtoContract]
enum MyEnum
{
[ProtoEnum(Value=1)]
Default,
[ProtoEnum(Value=10)]
Foo
}
使用这些属性,Default
通常会序列化为0
而Foo
会1
,现在它们将序列化为1
和10
分别
我想要做的是使用ProtoBuf.Meta
中的接口来模仿这种行为,所以我不必注释枚举(因为我通常不会在我的项目中控制它们)。
通过protobuf-net的来源,我设法得到以下(简化了一点)工作:
var model = RuntimeTypeModel.Create();
var meta = model.Add(enumType, applyDefaultBehaviour: true);
var fields = meta.GetFields();
// Oh god why
var fieldNumber =
typeof(ValueMember).GetField(
"fieldNumber",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic
);
List<string> ordered = GetDesiredEnumOrder(enumType);
int equiv = 0;
foreach (var val in ordered)
{
var field = fields.Single(f => f.Name == val);
fieldNumber.SetValue(field, equiv);
equiv++;
}
但是,我不能依靠反映到私人(只读!)字段,这只是要求麻烦。
那么,有没有一种支持的方法在protobuf-net中在运行时覆盖枚举线值?
答案 0 :(得分:2)
我不是在PC上检查这个,所以如果我正在疯狂谈话你就必须纠正我,但它应该是(在应用程序的早期):
RuntimeTypeModel.Default.Add(typeof(MyEnum), false)
.Add(1, "Default").Add(10, "Foo");
第一行告诉它向模型中添加新的Type
,没有(false
)应用任何常规规则;第二行将2个成员添加到该类型的表示中,并带有所需的值。
如果这不起作用(我将在今天晚些时候尝试检查),请告诉我,我将使工作(或提供等效的API)。可能只是因为在没有属性的情况下工作时,这个场景根本没有让我验证它。