在 protobuf-net ,您可以使用 ProtoEnumAttribute
覆盖枚举的有线格式,如下所示:
[ProtoContract]
enum MyEnum
{
[ProtoEnum(Value=1)]
Default,
[ProtoEnum(Value=10)]
Foo
}
使用这些属性,Default
通常会序列化为 0
和 Foo
为 1
,现在它们将序列化分别为 1
和 10
。
我想做的是使用 ProtoBuf.Meta
中的接口(interface)来模仿这种行为,所以我不必注释枚举(因为我通常不在我的项目中控制它们)。
通过挖掘 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++;
}
但是,我无法依靠反射到私有(private)(只读!)字段来传递它,这只是自找麻烦。
那么,是否有一种受支持的方法可以在运行时在 protobuf-net 中覆盖枚举线值?
最佳答案
我不在电脑前检查这一点,所以如果我胡言乱语,你必须纠正我,但它应该是这样的(在应用程序的早期):
RuntimeTypeModel.Default.Add(typeof(MyEnum), false)
.Add(1, "Default").Add(10, "Foo");
第一行告诉它向模型添加一个新的Type
,不(false
)应用任何常用规则;第二行向该类型的表示添加 2 个成员以及所需的值。
如果这不起作用(我会在今天晚些时候尝试检查),请告诉我,我会让它起作用(或提供等效的 API)。可能只是在没有属性的情况下工作时,这种情况根本没有出现让我验证它。
关于c# - 具有 ProtoBuf.Meta 接口(interface)的模仿 ProtoEnumAttribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13783894/