11

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!

Ian
  • 33,605
  • 26
  • 118
  • 198
hillsprig
  • 307
  • 5
  • 12
  • Hi, what is info variable? What is the format of serialization? Xml or binary? – The Smallest Dec 02 '10 at 20:40
  • 1
    it's the SerializationInfo that I use in the GetObjectData and the Serialization-constructor, sorry should have mentioned that. – hillsprig Dec 02 '10 at 20:41
  • http://stackoverflow.com/questions/126155/c-array-xml-serialization Any help? – Polity Dec 02 '10 at 20:42
  • 1
    What is line for Trade[] trades = (Trade[])Trades.ToArray();? Why don't you just say var trades = Trades.ToArray(); (Linq Extension) – The Smallest Dec 02 '10 at 20:44
  • Polity: I'm doing binary serialization so I don't think I have such tags available. – hillsprig Dec 02 '10 at 20:45
  • The_Smallest: For some reason I thought I had to give the types everywhere :) works without though. I'm going to test if it makes any difference in the result. EDIT: I made the Trade[] syntax change, although obviously no changes in the results. – hillsprig Dec 02 '10 at 20:47
  • Please show your Trade class (I think you have error there) – The Smallest Dec 02 '10 at 21:03
  • I've run into this a couple of times now, its a right pain :( – Ian Jan 11 '11 at 11:44

1 Answers1

12

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());
    }
}
The Smallest
  • 5,713
  • 25
  • 38