.NET Deserialisation with OnDeserializing and OnDeserialized

前端 未结 3 678
一向
一向 2020-12-28 17:02

I use a simple class that is serializable. It has a constructor for the deserialization:

protected MyClass(SerializationInfo info, StreamingContext context)
         


        
3条回答
  •  灰色年华
    2020-12-28 17:30

    The order of the calls depend on wether the object is the root of the serialized tree or some member of an object, which is also serialized in the same object graph. I get the following output with the extended example provided by Marc Gravell:

    SerRoot.ctor
    SerMember.ctor
    > serializing
    SerRoot.OnSerializingMethod
    GetObjectData
    SerMember.OnSerializingMethod
    SerMember.GetObjectData
    SerRoot.OnSerializedMethod
    SerMember.OnSerializedMethod
    < serializing
    > deserializing
    SerRoot.OnDeserializingMethod
    SerMember.OnDeserializingMethod
    SerMember.OnDeserializedMethod
    SerMember.ctor(info, context)
    SerRoot.ctor(info, context)
    SerRoot.OnDeserializedMethod
    < deserializing
    

    Notice that in deserialization SerMember.ctor is called after SerMember.OnDeserializedMethod! This is the code:

            static void Main(string[] args)
        {
            using (var ms = new MemoryStream())
            {
                var orig = new SerRoot();
                var ser = new BinaryFormatter();
                System.Console.WriteLine("> serializing");
                ser.Serialize(ms, orig);
                System.Console.WriteLine("< serializing");
                ms.Position = 0;
                System.Console.WriteLine("> deserializing");
                ser.Deserialize(ms);
                System.Console.WriteLine("< deserializing");
            }
        }
    [Serializable]
    class SerRoot : ISerializable
    {
        public SerMember m;
        public SerRoot()
        {
            System.Console.WriteLine("SerRoot.ctor");
            m = new SerMember();
        }
        protected SerRoot(SerializationInfo info, StreamingContext context)
        {
            System.Console.WriteLine("SerRoot.ctor(info, context)");
            m = info.GetValue("m", typeof(SerMember)) as SerMember;
        }
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            System.Console.WriteLine("GetObjectData");
            info.AddValue("m", m);
        }
        [OnDeserializing()]
        internal void OnDeserializingMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnDeserializingMethod"); }
    
        [OnDeserialized()]
        internal void OnDeserializedMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnDeserializedMethod"); }
    
        [OnSerializing()]
        internal void OnSerializingMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnSerializingMethod"); }
    
        [OnSerialized()]
        internal void OnSerializedMethod(StreamingContext context) { System.Console.WriteLine("SerRoot.OnSerializedMethod"); }
    
    }
    [Serializable]
    class SerMember : ISerializable
    {
        string text;
        public SerMember() 
        { 
            System.Console.WriteLine("SerMember.ctor");
            text = "test";
        }
        protected SerMember(SerializationInfo info, StreamingContext context) 
        {
            System.Console.WriteLine("SerMember.ctor(info, context)");
            text = info.GetString("text");
        }
        public void GetObjectData(SerializationInfo info, StreamingContext context) 
        { 
            System.Console.WriteLine("SerMember.GetObjectData");
            info.AddValue("text", text);
        }
        [OnDeserializing()]
        internal void OnDeserializingMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnDeserializingMethod"); }
    
        [OnDeserialized()]
        internal void OnDeserializedMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnDeserializedMethod"); }
    
        [OnSerializing()]
        internal void OnSerializingMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnSerializingMethod"); }
    
        [OnSerialized()]
        internal void OnSerializedMethod(StreamingContext context) { System.Console.WriteLine("SerMember.OnSerializedMethod"); }
    
    }
    

提交回复
热议问题