Protobuf-net serialisiert Liste nicht

Sep 29 2020

Ich experimentiere derzeit mit protobuf-net (v3.0.29) und versuche, einige einfache Klassen zu serialisieren / deserialisieren. Aus dem minimalen Arbeitsbeispiel verstehe ich nicht, warum protobuf-net das Einfache List<int> Valuezu einer Liste ohne Elemente serialisiert / deserialisiert .

    public enum BigEnum { One, Two }

    [ProtoContract]
    public class Container
    {
        [ProtoMember(1)]
        public BigEnum Parameter { get; private set; }
        [ProtoMember(2)]
        public List<int> Value { get; set; }
        public Container()
        {
            Parameter = BigEnum.One;
            Value = new List<int>();
        }
    }
    static class Program
    {
        static void Main(string[] args)
        {
            Container data = new Container();
            data.Value.Add(-1);
            data.Value.Add(1);

            MemoryStream memStream = new MemoryStream();
            Serializer.Serialize<Container>(memStream, data);
            var result = Serializer.Deserialize<Container>(memStream);
        }
    }

Diese Protobuf-Datei wurde von Serializer.GetProto () generiert und sieht für mich gut aus. Wie können wir List<int> Valuerichtig verarbeiten und kann protobuf-net mit komplexeren Strukturen wie List<KeyValuePair<String, String>>oder Dictionary<int,double>innerhalb einer Klasse umgehen ? Es gibt einige sehr alte Beiträge für protobuf-net mit Wörterbüchern, aber ich weiß nicht, wie der aktuelle Status ist.

syntax = "proto3";
package NetCoreProtobuf;

enum BigEnum {
   One = 0;
   Two = 1;
}
message Container {
   BigEnum Parameter = 1;
   repeated int32 Value = 2 [packed = false];
}

Antworten

1 MarcGravell Sep 28 2020 at 23:18

Ganz einfach: Sie haben den Stream nicht zurückgespult, sodass er von der aktuellen Position gelesen wurde - am Ende des Streams mit null zu lesenden Bytes. Es ist zufällig der Fall, dass Null-Bytes in protobuf vollkommen gültig sind, so dass hier keine Ausnahme ausgelöst werden kann, da Sie beim Deserialisieren von Null-Bytes möglicherweise völlig richtig sind.

Serializer.Serialize<Container>(memStream, data);
memStream.Position = 0;
var result = Serializer.Deserialize<Container>(memStream);

Oder einfacher: Verwenden Sie die DeepCloneMethode:

var clone = Serializer.DeepClone(data);