Поведение сериализации Protobuf-net enum изменено в вер.2.3.0 - PullRequest
3 голосов
/ 14 марта 2019

Любой сериализованный объект до 2.3.0 не будет правильно десериализован в 2.3.0 или новее, если он содержит значения перечисления и использует DataMember с InferTagFromNameDefault вместо ProtoMember.

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

public enum MyEnum
{
    FirstValue,
    SecondValue
}

У меня есть этот класс.Сериализация с использованием этого кода.

{
    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 это приведет к байту [] {8, 2}, а после 2.3.0 - к байту [] {8, 1}

Есть ли способ заставить сериализовать более поздние версии так же, как и более ранние?

1 Ответ

2 голосов
/ 19 марта 2019

Это ... неожиданно.Я еще не понимаю, что здесь произошло, но вы правы, что произошли изменения.Исторически сложилось так, что при использовании InferTagFromNameDefault в значениях перечисления было смещение 1, и проверка «enum passthru» не в состоянии это учесть (здесь «enum passthru» теперь оценивается как true, гдебыло бы false ранее).

Следующее, кажется, исправляет это во время выполнения:

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

или с помощью атрибутов:

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

Я выясню, чтослучилось здесь.

...