Я пытался добавить новое значение enum для определенного класса protobuf-serialized в новой версии приложения, а во время тестирования заметил, что предыдущая версия генерирует исключение, учитывая этот новый формат файла :Protobuf-net enum обратная совместимость
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
это довольно очевидно, что это говорит мне, что нет никакого значения перечисления для int
значения 3
, но я всегда была идея, что Protocol Buffers defaulted to the zero-valued ("default") enum value (если таковая существует), в случае, если фактическое значение перечисления не удалось сопоставить.
Чтобы уточнить, это может быть воспроизведен с помощью следующего примера (я намеренно делаю шаг десериализации в другой класс, чтобы имитировать старые приложения пытается загрузить новый формат):
// --- 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, чтобы использовать отдельное свойство и оставить значения перечисления неизмененными, но я хотел бы сделать переходы обратно совместимыми, если это возможно.
Что должно произойти, чтобы '' v1roundtrip.Value' когда EnumV2.Three' был отправлен? – Caramiriel
@Caramiriel: Согласно моему пониманию (объяснено в [этой теме] (http://stackoverflow.com/q/10392952/69809)), он должен был быть установлен в 'EnumV1.Default' вместо того, чтобы бросать исключение. Этого я ожидал бы, если бы я хотел убедиться, что формат обратно совместим. Например, [этот пользователь] (http://stackoverflow.com/a/13924171/69809), похоже, имел такую же проблему и исправил его, добавив значение перечисления по умолчанию (нуль), без дополнительных атрибутов protobuf. – Groo
ping @marcgravell – jgauffin