【问题标题】:Protobuf-net how to serialize List<T>Protobuf-net 如何序列化 List<T>
【发布时间】:2015-01-14 16:29:47
【问题描述】:

这是我当前的序列化/反序列化代码

// SERIALIZE
using (var file = File.Create(@"..\..\SavedPCInfo.bin"))
{
    Serializer.Serialize(file, pcs);
}

//DESERIALIZE
if (File.Exists(FileName))
{
     using (var file = File.OpenRead(@"..\..\SavedPCInfo.bin"))
     {
          pcs = Serializer.Deserialize<List<PC>>(file);
     }
}

其中pcsPC 对象的列表。截至目前,我在反序列化时遇到错误:

没有找到适用于 PC 的无参数构造函数

我不知道为什么它需要一个无参数的构造函数来进行反序列化,但我只是想让我的反序列化工作。关于如何实现的任何想法?我似乎在这里做错了什么。

【问题讨论】:

  • 我会考虑序列化数组而不是自定义集合类型,例如 List。你需要序列化数据,而不是类型。
  • 很抱歉,我看不出有什么不同。我更喜欢列表,因为在其项目上执行迭代任务很容易。除非这里面有隐患,否则我可能会重新考虑。

标签: c# serialization protobuf-net


【解决方案1】:

你有几个选择:

  1. PC 中创建一个私有的无参数构造函数。它将在反序列化时调用。

  2. [ProtoContract(SkipConstructor = true)] 属性应用于PC。在这种情况下,对象将在未初始化状态下被实例化。

    请谨慎使用:如果您在类中的任何构造函数之外将字段初始化为某些默认值,则不会发生这些初始化。

    例子:

    [ProtoContract(SkipConstructor = true)]
    public class PC
    {
        private int _something = 42;
    
        public int Something { get { return _something; } }
    
        public PC(string foo)
        {
        }
    }
    

    在这种情况下,Something 将在反序列化对象上返回 0

【讨论】:

  • 选项 1 解决了它,但为什么需要无参数构造函数?
  • @Jer 因为 protobuf 不知道如何实例化对象(它不知道要为构造函数提供哪些参数)。第二种解决方案使用完全不同的方法来创建对象 (FormatterServices.GetUninitializedObject)。
【解决方案2】:

如果您使用像 json-io 这样的序列化库,它将 Java 序列化为 JSON(反之亦然),您通常不需要添加任何构造函数。该库将使用对象上现有的构造函数(必要时甚至是私有构造函数)来实例化您的对象。

转为 JSON 格式进行序列化还有一个额外的好处,那就是序列化数据以人类可读的形式呈现。

json-io:https://github.com/jdereg/json-io 编辑您的 JSON:http://www.jsoneditoronline.org/

一行将序列化您的数据:

String json = JsonWriter.objectToJson(root);

一行会反序列化它:

Object root = JsonReader.jsonToJava(json);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-20
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-18
    相关资源
    最近更新 更多