Próbowałem dodać nową wartość wyliczeniową dla pewnej klasy z serią protobuf w nowej wersji aplikacji, a podczas testowania zauważyłem, że poprzednia wersja wygeneruje wyjątek, biorąc pod uwagę ten nowy format pliku :Protobuf-net enum zgodność wsteczna
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
jest dość oczywiste, że to mówi mi, że nie ma wartości wyliczenia dla wartości int
z 3
, ale zawsze miałem pojęcia, że Protocol Buffers defaulted to the zero-valued ("default") enum value (jeśli taki istnieje), w przypadku gdy rzeczywista wartość enum nie można przypisać do.
celu wyjaśnienia, to może być powielana stosując następujący przykład (jestem celowo robi krok deserializacjia do innej klasy naśladować starą aplikację próby załadowania nowego formatu):
// --- 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; }
}
i następujący kod zawiedzie:
// 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);
Od V1 jest na otwartej przestrzeni, jest jakiś metadanych można używać podczas szeregowania w v2, aby uniknąć tego problemu? Mogę, oczywiście, wydostać się z tego problemu, przepisując v2, aby użyć oddzielnej właściwości i pozostawić wartości wyliczeniowe niezmodyfikowane, ale chciałbym, aby w miarę możliwości były one zgodne wstecz.
Co powinno się zdarzyć na '' EnumV2.Three' v1roundtrip.Value' kiedy został wysłany? – Caramiriel
@Caramiriel: Zgodnie z moim zrozumieniem (wyjaśnione w [tym wątku] (http://stackoverflow.com/q/10392952/69809)), powinien on zostać ustawiony na 'EnumV1.Default' zamiast rzucać wyjątek. Tego bym się spodziewał, jeśli chcę, aby format był kompatybilny wstecz. Na przykład wydaje się, że [ten użytkownik] (http://stackoverflow.com/a/13924171/69809) miał ten sam problem i naprawił go, dodając domyślną wartość zerową, bez dodatkowych atrybutów protobuf. – Groo
ping @marcgravell – jgauffin