Protobuf-net 枚举序列化行为在版本中发生了变化。 2.3.0

Protobuf-net enum serialization behaviour changed in ver. 2.3.0

如果 2.3.0 之前的任何序列化对象包含枚举值并且使用 DataMember 和 InferTagFromNameDefault 而不是 ProtoMember,则在 2.3.0 或更高版本中将无法正确反序列化。

[DataContract]
public class ClassWithEnum
{
    [DataMember]
    public MyEnum Enum { get; set; }
}

public enum MyEnum
{
    FirstValue,
    SecondValue
}

我有这个class。使用此代码对其进行序列化。

{
    RuntimeTypeModel.Default.InferTagFromNameDefault = true;

    var v = new ClassWithEnum { Enum = MyEnum.SecondValue };

    using (var memoryStream = new MemoryStream())
    {
       Serializer.Serialize(memoryStream, v);
       var bytes = memoryStream.ToArray();
    }
}

在 2.3.0 之前,这将导致 byte[] { 8, 2 } 在 2.3.0 之后它将导致 byte [] { 8, 1 }

有什么方法可以使以后的版本以与早期版本相同的方式序列化吗?

这……出乎意料。我还不明白这里发生了什么,但你是对的,发生了变化。从历史上看,使用 InferTagFromNameDefault 时,枚举值似乎有一个 1 的偏移量,而 "enum passthru" 检查无法解决这个问题("enum passthru" 现在评估为 true 在这里,以前应该是 false)。

以下似乎可以在运行时修复此问题:

RuntimeTypeModel.Default.Add(typeof(MyEnum), true).EnumPassthru = false;

或通过属性:

[ProtoContract(EnumPassthru = false)]
public enum MyEnum
{...}

我会调查这里发生的事情。