Question

I have a custom abstract base class with sub classes that I've made serializable/deseriablizeable with ISerializable. When I do serialization/deserialization of single instances of this class' sub classes, everything works fine. However, when I do an array of them I always end up with an array of nulls on deserialization. Serialization is done with BinaryFormatter.

The items are contained within a:

public ObservableCollection<Trade> Trades { get; private set; }

On serialization this is done in GetObjectData on the SerializationInfo parameter:

Trade[] trades = (Trade[])Trades.ToArray<Trade>();
            info.AddValue("trades", trades);

And on deserialization this is done in the serialization constructor also on the SerializationInfo parameter:

Trade[] trades = (Trade[])info.GetValue("trades", typeof(Trade[]));

            foreach (Trade t in trades)
            {
                Trades.Add(t);
            }

Deserialization always gives me an array of nulls and as I mentioned earlier, a single item serializes and deseriaizes just fine with this code:

Serialization (GetObjectData method):

info.AddValue("trade", Trades.First<Trade>());

Deserialization (Serialization Constructor):

Trade t = (Trade)info.GetValue("trade", typeof(Trade));
            Trades.Add(t);

Is this a common problem? I seem to find no occurrences of anyone else running in to it at least. Hopefully there is a solution :) and if I need to supply you with more information/code just tell me.

Thanks!

Was it helpful?

Solution

Array deserializes first. Then all inner deserialization is done. So when you try to access items, they are null.

And idea to use [OnDeserialized] Attribute on some method, that builds up all other properies. And here is example:

[Serializable]
public class TestClass : ISerializable
{
    private Trade[] _innerList;
    public ObservableCollection<Trade> List { get; set; }

    public TestClass()
    { }

    [OnDeserialized]
    private void SetValuesOnDeserialized(StreamingContext context)
    {
        this.List = new ObservableCollection<Trade>(_innerList);
        this._innerList = null;
    }

    protected TestClass(SerializationInfo info, StreamingContext context)
    {
        var value = info.GetValue("inner", typeof(Trade[]));
        this._innerList = (Trade[])value;
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("inner", this.List.ToArray());
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top