Question

I am facing a problem of inconsistency after deserialization using protobuf-net.

The class I would like to serialize/deserialize looks like:

[ProtoContract]
public class TSS
{
    [ProtoMember(1, AsReference = true)]
    public EventManager eventManager { get; private set; }

    [ProtoMember(2)]
    public DateTime referenceDateTime { get; private set; }

    [ProtoMember(3)]
    public Mode mode;
}

And inside EventManager class, it looks like:

[ProtoContract]
public class EventManager
{
    [ProtoMember(1)]
    public InputQueue inputQueue = new InputQueue();
    [ProtoMember(2)]
    public InputQueue InputQueue
    {
        get { return this.inputQueue; }
        set { this.inputQueue = value; }
    }
    [ProtoMember(7, AsReference = true)]
    public TSS tss;
}

The tss in class EventManager is a reference of TSS object, and eventManager in class TSS is a reference of EventManager object. This is the reason I put AsReference = true there (is this the right way?)

I do serialization like:

public void StateSaving(int time, TSS tss)
{
    Stream memoryStream = new MemoryStream();
    Serializer.Serialize(memoryStream, tss);
    states.Add(time, memoryStream);
}

and do deserialization like:

public void Deserialize(int time, ref TSS tss)
{
    Stream memoryStream = states[time];
    memoryStream.Position = 0;
    tss = Serializer.Deserialize<TSS>(memoryStream);
}

The problem is that whenever I do deserialization, the data structures like inputQueue in the EventManager is populated with NULL values instead of actual values at that point. I am a newbie to protobuf-net, so please point out any mistakes (I believe there are a lot).

Thanks in advance!!

Was it helpful?

Solution

(from comments)

I have located the problem, basically there's a list that needs to be deserialized. And this list is a list of events, in which the constructors of the events have parameters, and when it tries to deserialize, the program will run the parameterless constructors (I manually added these constructors in order to eliminate the exceptions) instead of the right ones (with parameters). I know this is how serialization/deserialization work, but is there a way I can serialize and deserialize this list correctly?

Ah, indeed. There are various approaches when it comes to object construction:

  • use the parameterless constructor
  • look for a constructor which matches all the defined members
  • skip the constructor completely
  • use a custom object factory
  • use a surrogate object and custom conversion

Things like XmlSerializer use the first; things like DataContractSerializer and BinaryFormatter use the 3rd; the good news is that protobuf-net supports all 5. I suggest that in your case the best option is to use the 3rd option for this type, which you can do by:

[ProtoContract(SkipConstructor=true)]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top