4

我在使用 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

我该如何解决这个问题?

4

2 回答 2

1

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

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

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

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

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

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

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

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

于 2012-11-28T20:45:46.130 回答
1

您需要将其用于 CrazList 属性;

[ProtoBuf.ProtoContract(IgnoreListHandling=true)]
于 2012-11-28T19:28:29.830 回答