Question

This is my class:

namespace myclass
{
    [Serializable]
    public class BasicGameObject : GameObject
    {
      protected Shadow shadow_ = null;
      protected bool shadow_enabled_ = false;

      protected Dictionary<string, AnimationManager> animations_ = new Dictionary<string, AnimationManager>();
      protected Dictionary<string, string> loaded_textures_ = new Dictionary<string, string>();

      protected string current_animation_;

      protected int frame_width_;
      protected int frame_height_;

//Costructor and other methods
//...

    [OnDeserialized]
    private void OnDeserialized(StreamingContext context)
    {
        Console.WriteLine("BasicGameObject");
        foreach (KeyValuePair<string, AnimationManager> anim in animations_)
        {
            animations_[anim.Key].Reload(Loader.GameObjectTexturesList[loaded_textures_[anim.Key]]);
        }
    }

When I deserialize this object, I need it to reload every texture stored in "animations_". If I put a breakpoint on Console.WriteLine("BasicGameObject");, and click on anim, the debugger shows me that anim's Count is at 0, but every other variable has the right value. (I'm sure that while saving, it wasn't at 0)

What's the problem?

How I load the object (SERIALIZATIONOBJECT_ just contains a list of BasicGameObject):

    IFormatter formatter = new BinaryFormatter();
    SERIALIZATIONOBJECT_ = (SerializationObject)formatter.Deserialize(stream);
    stream.Close();

After this, (and after OnDeserialized call!), If i do some test, I see that anim of my object, has the right value. Why here and not inside "OnDeserialized"?

I just want to note that before I was using the same identical function that now is in OnDeserialized without the attribute, but just as a function, and I was calling it after deserialization. I saw the possibility di automatize it and I thought it was good. Maybe it hides something.

Was it helpful?

Solution

According to the MSDN documentation for the OnDeserialized attribute:

When applied to a method, specifies that the method is called immediately after deserialization of an object in an object graph. The order of deserialization relative to other objects in the graph is non-deterministic.

the method OnDeserialize is called after the object was deserialized but (to my understanding) not necessarily after all aggregated objects were also deserialized.

You are performing an operation in your OnDeserialized method which uses the aggregated animations_ dictionary containing AnimationManager objects which must also be deserialized. If OnDeserialized is called before the AnimationManager objects are deserialized, it would explain the symptoms you described.

Best you call the method yourself and remove the OnDeserialized attribute.

OTHER TIPS

XmlSerializer only serializes and deserializes public fields and properties.

See the MSDN documentation :

XML serialization is the process of converting an object's public properties and fields to a serial format (in this case, XML) for storage or transport. [...]

You may want to use a data transfer object (DTO) in this situation. The DTO is an internal class which holds all the data for your game object as public fields or properties which can be serialized and deserialized. Then simply aggregate the DTO to your game object and access the data via the DTO.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top