Protobuf-net c# serialization/deserialization of list 导致空集合

Protobuf-net c# serialization/deserialization of list result in empty collection

我正在尝试序列化和反序列化 List<T>

最后的 objective 正在序列化对象列表/API 的对象。

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

经过一些阅读我还没有解决这个问题。 这是我用于测试的简单代码,但也用于我的 serialization/deserialization classes:

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~ 个元素)

主机很简单 class:

[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 个元素的集合。

怎么了,我错过了什么?

谢谢

你试过 r 和 stream2 吗?

此处:

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

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

选项:

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

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

var r = Serializer.DeepClone(data);