【问题标题】:protobuf-net List<> inheritance deserializationprotobuf-net List<> 继承反序列化
【发布时间】:2012-11-16 17:28:33
【问题描述】:

我在使用 protobuf-net 进行反序列化时遇到问题。

我有以下课程:

[ProtoContract]
public class CrazyList : List<string>
{
    [ProtoMember(1)]
    private readonly string _foo;

    public CrazyList(string foo)
    {
        _foo = foo;
    }

    public CrazyList(){}

    public new void Add(string item)
    {
        Console.Write(item + foo); // Problem is here!

        base.Add(item);
    }

}

并像这样使用它:

var list = new CrazyList("world!");
list.Add("Hello ");

using (var ms = new MemoryStream())
{
    Serializer.Serialize(ms, list);

    ms.Position = 0;

    var listDS = Serializer.Deserialize<CrazyList>(ms);
    listDS.Add("Goodbye ");
}

方法Add_foo 字段反序列化完成之前触发。

我该如何解决这个问题?

【问题讨论】:

    标签: c# list serialization protocol-buffers protobuf-net


    【解决方案1】:

    您需要将其用于 CrazList 属性;

    [ProtoBuf.ProtoContract(IgnoreListHandling=true)]
    

    【讨论】:

      【解决方案2】:

      与 XmlSerializer 一样,一个列表,或者一个叶子。没有“两者”。目前,它将检测“列表”,并且不会寻找叶子成员。您可以将其更改为叶子(请参阅 Fredou 的回答),但它不会序列化项目。

      由于电线规范(谷歌,而不是我),列表本身没有表示:重复的序列只是:“项目,项目,项目,项目”。因此,如果某物是一个列表,那么我实际上无处可以存储与列表本身相关的数据。

      坦率地说,最简单的选择是重构封装,例如(为简洁起见):

      class SomeWrapper {
          string Foo ...
          List<string> Items ... 
      }
      

      如果需要,您也可以作弊,方法是使用 Fredou 展示的方法,并添加:

      [ProtoMember(2)]
      private IList<string> Items { get { return this; } }
      

      这会让它看起来像上面的最小示例,而不会以任何重要的方式实际更改模型。

      顺便说一句:不建议为 List&lt;T&gt; 子类提供自定义 Add,并且您不应依赖反序列化顺序。

      【讨论】:

        猜你喜欢
        • 2012-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        • 2012-10-10
        相关资源
        最近更新 更多