Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deserializing a generic list returns null

I'm de/serializing an object like so:

public class myClass : ISerializable
{
  public List<OType> value;

  public myClass(SerializationInfo info, StreamingContext context)
  {
    this.value = (List<OType>)info.GetValue("value", typeof(List<OType>));
  }

  void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  {
    info.AddValue("value", value, typeof(List<OType>));
  }
}

The object that is in the list does have the Serializable attribute. When serializing, no errors are thrown and the list is never empty, but when deserializing all of my lists are null and I'm not sure why.

I'm marking this as answered by CQ. I was able to produce a small one off test app that does properly serialize/deserialize with the objects I'm trying to use but I still can't seem to get it to work in my production code but I suspect it's something small that I'm missing.

like image 785
Steven Evers Avatar asked Feb 05 '09 18:02

Steven Evers


2 Answers

When you say that your list is null, do you mean that the list itself is null, or that it filled with null entries? If the latter, then this is a known .Net problem: see my question on the same problem.

Basically, List<T>s are only initialized when they are deserialized; the objects that they contain are only deserialized after the object graph has been deserialized. One way around this is to put any code which requires them in an OnDeserialized method, or one with an [OnDeserializedAttribute]. See MSDN.

like image 82
Joel in Gö Avatar answered Oct 20 '22 09:10

Joel in Gö


Well the list is always empty to begin with, are you setting it via myClass.value = new List<...>(); ? Also have you saved the serialized data in both binary and xml formats so you can verify data is actually being saved?

Just a note as well, if you are using 2.0+ you don't have to implement ISerializable if you don't need to control the absolute serialization, you can change value to a public property and it will serialize on it's own.

Edit: The following case seems to serialize and deserialize fine for me, I am posting this incase I am misunderstanding the question as a whole.

Ignoring the nasty test code, hopefully this helps a little.

    [Serializable]
    public class OType
    {
        public int SomeIdentifier { get; set; }
        public string SomeData { get; set; }

        public override string ToString()
        {
            return string.Format("{0}: {1}", SomeIdentifier, SomeData);
        }
    }

    [Serializable]
    public class MyClass : ISerializable
    {
        public List<OType> Value;

        public MyClass() {  }

        public MyClass(SerializationInfo info, StreamingContext context)
        {
            this.Value = (List<OType>)info.GetValue("value", typeof(List<OType>));
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("value", Value, typeof(List<OType>));
        }
    }

...

        var x = new MyClass();

        x.Value = new OType[] { new OType { SomeIdentifier = 1, SomeData = "Hello" }, new OType { SomeIdentifier = 2, SomeData = "World" } }.ToList();

        var xSerialized = serialize(x);

        Console.WriteLine("Serialized object is {0}bytes", xSerialized.Length);

        var xDeserialized = deserialize<MyClass>(xSerialized);

        Console.WriteLine("{0} {1}", xDeserialized.Value[0], xDeserialized.Value[1]);

Forgot the output..

Serialized object is 754bytes

1: Hello 2: World

like image 27
Quintin Robinson Avatar answered Oct 20 '22 08:10

Quintin Robinson