Protobuf-net C#列表的序列化/反序列化导致空集合

时间:2018-08-13 09:41:59

标签: c# protobuf-net

我正在尝试对List<T>进行序列化和反序列化。

最终目标是序列化API的对象/对象列表。

Protobuf-net 2.3.17(撰写本文时为最后一个)

一些阅读后,我还没有解决这个问题。 这是我用于测试的简单代码,但也用于我的序列化/反序列化类:

using (var stream = new MemoryStream())
   {
      Serializer.Serialize(stream, data);
      var x = stream.ToArray();

      using (var stream2 = new MemoryStream(x))
        {
          var r = Serializer.Deserialize<List<Host>>(stream);
        }
    }

数据是List<Host>(150个元素)

主机是一个简单的类:

[Serializable]
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic, SkipConstructor = true)]
    public class Host
    {
        public Guid GidHost { get; set; }
        public int IdA { get; set; }
        public string HostName { get; set; }
        public string Description { get; set; }

        [DefaultValue(StatusEnum.Undefined)]
        public HostStatusEnum Status { get; set; }

        public string Address { get; set; }
        ecc.. (some other public primitive variables)

       [Serializable]
       public enum StatusEnum
       {
           Undefined = 0,
           Ok = 1,
           Offline = 2
       }
}

同时x(我想)已正确序列化(x包含33000字节) r是一个包含0个元素的集合。

出什么问题了,我想念什么?

谢谢

2 个答案:

答案 0 :(得分:1)

您是否尝试过将stream2用于r?

答案 1 :(得分:1)

这里:

using (var stream2 = new MemoryStream(x))
{
  var r = Serializer.Deserialize<List<Host>>(stream);
}

您正在从stream开始反序列化,而不是从stream2开始反序列化。 stream当前位于末尾,因此实际上有0个字节可供读取。 0字节实际上是完全有效的protobuf,在这种情况下将表示一个空列表。

选项:

  • stream2反序列化
  • 倒退stream
  • 使用Serializer.DeepClone

在这种情况下,我建议使用最后一个选项,因为它将避免额外的数组分配。从3.0开始,DeepClone还可以选择不同的序列化存储策略(StreamPipe等)来最适合您的平台-因此:在.NET Core 2.1上,它可能更喜欢使用{{ 1}},并利用“跨度”等。

Pipe