7

I would like to serialize and deserialize some values stored in an object array.

public class Sample
{
    public object[] Data;
}

I know at run-time what types to expect in the array. In effect I want to treat Data inside of Sample as a message stream.

Individually, I know I can use Serializer.NonGeneric.SerializeWithLengthPrefix to write each object out using a PrefixStyle.Base128 and make a Prefix->Type map for the Deserialise Type-Resolver. See What is protobuf-net SerializeWithLengthPrefix tag argument for?

What I'm struggling with is actually getting protobuf-net to do that automatically for me and then nesting that behavior within a an encompassing message. As far as I can tell the resulting messages in the stream would be perfectly valid.

For example; lets say I have this array of objects:

new object[]
{
    "Hello",
    42,
    0.3529321,
    true
}

and the tag-map

var typeToTag = new Dictionary<Type, int>()
{
    {typeof (string), 1},
    {typeof (int), 2},
    {typeof (double), 3},
    {typeof (bool), 4},
};

I can write each of them to a stream with the non-generic SerializeWithLengthPrefix

foreach (var value in data)
    Serializer.NonGeneric.SerializeWithLengthPrefix(
        stream,
        value,
        PrefixStyle.Base128,
        typeToTag[value.GetType()]);

now, separately (stored independently) I know there are 4 values in that message and I know (at run-time) the map

var tagToType = new Dictionary<int, Type>()
{
    {1, typeof (string)},
    {2, typeof (int)},
    {3, typeof (double)},
    {4, typeof (bool)},
};

then I can deserialise with

var expectedElements = 4;

var readObjects = new object[expectedElements];

for (int i = 0; i < expectedElements; i++)   
    Serializer.NonGeneric.TryDeserializeWithLengthPrefix(
        stream,
        PrefixStyle.Base128,
        (t) => tagToType[t], out readObjects[i]);

    }
}

That all works perfectly.

My issue is I want to bundle the above behavior so that protobuf-net uses it (serialize/deserialize the object stream with the given tag maps) when I try to serialise and deserialize an instance of Sample - effectively a message with a nested message stream.

Any help in steering me in the right direction is welcome. :)

Community
  • 1
  • 1
Meirion Hughes
  • 24,994
  • 12
  • 71
  • 122
  • 1
    Protobuf-net is a contract based serializer. Object is not a contract... Not sure it is sensible to try to do this... – Marc Gravell Aug 05 '14 at 16:54
  • Well, to be fair I do know the contract; just at run-time. – Meirion Hughes Aug 05 '14 at 18:11
  • 1
    In fact you made this very point: "with a heterogeneous set of objects, you can use the Serializer.NonGeneric API to allow type-resolution based on the tag, i.e. the code equivalent of "if 1 then Invoice; if 2 then Order, if 3 then skip it, if 4 then Customer", etc". http://stackoverflow.com/questions/8601647/what-is-protobuf-net-serializewithlengthprefix-tag-argument-for – Meirion Hughes Aug 06 '14 at 08:13

0 Answers0