我试图在一个新的应用程序版本中为某个 protobuf 序列化的类添加一个新的枚举值,并且在测试时,注意到在给定这种新文件格式的情况下,以前的版本会抛出异常:
An unhandled exception of type 'ProtoBuf.ProtoException' occurred in protobuf-net.dll Additional information: No {enum-type-name} enum is mapped to the wire-value 3
It is fairly obvious that it's telling me that there is no enum value for the int
value of 3
, but I always had the idea that Protocol Buffers defaulted to the zero-valued ("default") enum value (if such exists), in case that an actual enum value couldn't be mapped to.
To clarify, this can be reproduced using the following example (I am intentionally doing the deserialization step into a different class to mimic old app trying to load the new format):
// --- version 1 ---
public enum EnumV1
{
Default = 0,
One = 1,
Two = 2
}
[ProtoContract]
public class ClassV1
{
[ProtoMember(1)]
public EnumV1 Value { get; set; }
}
// --- version 2 ---
public enum EnumV2
{
Default = 0,
One = 1,
Two = 2,
Three = 3 // <- newly added
}
[ProtoContract]
public class ClassV2
{
[ProtoMember(1)]
public EnumV2 Value { get; set; }
}
下面的代码会失败:
// serialize v2 using the new app
var v2 = new ClassV2() { Value = EnumV2.Three };
var v2data = Serialize(v2);
// try to deserialize this inside the old app to v1
var v1roundtrip = Deserialize<ClassV1>(v2data);
既然 v1 是公开的,在 v2 中序列化时是否可以使用一些元数据来避免这个问题?当然,我可以通过重写 v2 以使用单独的属性并保持枚举值不变来摆脱这个麻烦,但我希望尽可能使枚举向后兼容。
最佳答案
将 [ProtoContract(EnumPassthru=true)]
添加到您的枚举中将允许 protobuf-net 反序列化未知值。
不幸的是,没有办法追溯修复您的 v1。您将不得不使用不同的属性。
关于c# - Protobuf-net 枚举向后兼容性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35600548/