Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnSerializingAttribute vs ISerializable

I was reading custom serialization article on msdn: http://msdn.microsoft.com/en-us/library/ty01x675%28VS.80%29.aspx

It mentions that there are two ways of implementing custom serialization:
1, using OnDeserializedAttribute, OnDeserializingAttribute, OnSerializedAttribute, OnSerializingAttribute
2, implement ISerializable interface

According to MSDN, method #1 is "best practice and easiest", but I fail to understand how are the two methods even the same thing. To my understanding, the OnSerializing|OnSerialized|etc attributes allow you to hook methods to particular phases of the serialization, while ISerializable interface allows you to directly modify what goes into and comes out of SerializationInfo. Is this correct?

To put my confusion into context, how do you implement OnSerializing to serialize object field under different name? like the following code:

public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("i", n1);
    info.AddValue("j", n2);
    info.AddValue("k", str);
}

Update: Although Frederik Gheysels's answer is not completely correct (decorating with Serializable is pre-requisite for both OnSerializing/OnDeserializing attributes and ISerializable interface), he did however points out that OnSerializing/OnDeserializing attributes are meant to be supplement of ISerializable, so I am accepting his answer on this point.

like image 490
Bill Yang Avatar asked Sep 22 '09 22:09

Bill Yang


1 Answers

OnSerializing / OnDeserializing is complementary to ISerializable or SerializableAttribute.

In other words: OnSerializing / OnDeserializing is not an alternative for ISerializable or the SerializableAttribute.

These 2 attributes (OnSerializing / OnDeserializing) allow you to take control / perform extra actions when an object is serialized or deserialized. But, in order to be able to do this, the type to which these attributes are applied, has to be serializable (and thus implement the ISerializable interface, or decorated with the Serializable attribute).

This is also said like this in the MSDN article you're referring to: - OnSerializing and OnDeserializing are used to 'correct' data during and after serialization.

You can test it quite easily. Create a type like this, and try to serialize it:

public class Foo
{
    private int _bar = 5;

    [OnSerializing]
    public void OnSerializeFoo( StreamingContext context )
    {
        _bar = 10;
    }
}

Note that the type does not implement ISerializable, nor is it decorated with the SerializableAttribute. Try to serialize an instance of that type, and you'll be faced with a SerializationException, because Foo is not serializable.

So, you can use these attributes (OnSerializing, OnDeserializing) to implement additional logic that should be performed when an instance of a certain type is serialized or deserialized.

like image 178
Frederik Gheysels Avatar answered Oct 05 '22 11:10

Frederik Gheysels