使用ProtoBuf.Meta接口模仿ProtoEnumAttribute
在protobuf-net中 ,您可以使用ProtoEnumAttribute
覆盖枚举的有线格式, 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 ordered = GetDesiredEnumOrder(enumType); int equiv = 0; foreach (var val in ordered) { var field = fields.Single(f => f.Name == val); fieldNumber.SetValue(field, equiv); equiv++; }
但是,我不能依靠反映到私人(readonly!)字段,这只是要求麻烦。
那么,有没有一种支持的方法在protobuf-net中在运行时覆盖枚举线值?
我不是在PC上检查这个,所以如果我正在疯狂谈话你就必须纠正我,但它应该是类似的(早期在应用程序中):
RuntimeTypeModel.Default.Add(typeof(MyEnum), false) .Add(1, "Default").Add(10, "Foo");
第一行告诉它向模型添加一个新的Type
, 而不是 ( false
)应用任何通常的规则; 第二行将2个成员添加到该类型的表示中,并带有所需的值。
如果这不起作用(我今天晚些时候会尝试检查),请告诉我,我会让它工作(或提供一个等效的API)。 可能只是在没有属性的情况下,这种情况根本没有让我validation它。