4

I have problem with deserialization using protobuf-net.

I have the following class:

[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);
    }

}

And use it like this:

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 ");
}

The method Add is firing before the _foo field deserialization is completed.

How I can solve this problem?

Servy
  • 202,030
  • 26
  • 332
  • 449
epifun
  • 109
  • 7

2 Answers2

1

you need to use this for the CrazList attribut;

[ProtoBuf.ProtoContract(IgnoreListHandling=true)]
Fredou
  • 19,848
  • 10
  • 58
  • 113
1

As with XmlSerializer, something either is a list, or is a leaf. There is no "both". At the moment, it will detect "list", and won't look for leaf-members. You can change it to be a leaf (see Fredou's answer) but then it won't serialize the items.

Because of how the wire specification (by google, not me), there is no representation of the list itself: a repeated sequence is just: "item, item, item, item". So if something is a list there is literally nowhere I can store data relating to the list itself.

Frankly, the simplest option is to refactor to encapsulate, for example (being minimal for brevity):

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

You can also probably cheat if you need to, by using the approach Fredou shows, and adding:

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

Which will make it look like the minimal example above, without actually changing the model in any significant way.

Incidentally: providing a custom Add for a List<T> subclass is not recommended, and you should not rely on order of deserialization.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900