Mimic ProtoEnumAttribute with ProtoBuf.Meta interface

情到浓时终转凉″ 提交于 2019-12-24 02:08:04

问题


In protobuf-net, you can override the wire format for enumerations with the ProtoEnumAttribute like so:

[ProtoContract]
enum MyEnum
{
  [ProtoEnum(Value=1)]
  Default,
  [ProtoEnum(Value=10)]
  Foo
}

With those attributes, where Default would normally serialize to 0 and Foo to 1 they will now serialize to 1 and 10 respectively.

What I'm trying to do is mimic this behavior using interfaces in ProtoBuf.Meta, so I don't have to annotate enumerations (because I don't typically control them in my project).

Digging through protobuf-net's source, I've managed to get the following (simplified a bit) working:

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

However I can't ship this relying on reflecting into a private (readonly!) field, that's just asking for trouble.

So, is there a supported way to override enumeration wire values at runtime in protobuf-net?


回答1:


I'm not at a PC to check this, so you'll have to correct me if I'm making crazy-talk, but it should be something like (early on in the app):

RuntimeTypeModel.Default.Add(typeof(MyEnum), false)
    .Add(1, "Default").Add(10, "Foo");

The first line tells it to add a new Type to the model, without (false) applying any of the usual rules; the second line adds 2 members to that type's representation, with the required values.

If that doesn't work (and I'll try to check later today), let me know and I'll make it work (or provide an equivalent API). It could just be that this scenario simply hasn't come up for me to verify it when working without attributes.



来源:https://stackoverflow.com/questions/13783894/mimic-protoenumattribute-with-protobuf-meta-interface

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!