Serialization is the process of saving an object onto a storage medium (such as a file, or a memory buffer) or transmiting it across a network connection link in binary form.

The .NET Framework provides an easy-to-use serialization mechanism by using the [Serializable] attribute. If so why do we need the ISerializable interface? Lets compare to see the differences…

1. The Serializable Attribute

Marking your class, struct, delegate or enum as [Serializable] indicates that this class can be serialized. The .Net runtime uses Reflection at runtime, and by default all public and private fields are serialized , unless you apply the NonSerializedAttribute.

[Serializable]
class MyClass
{
    public string FirstName { get; set; }
}

2. The ISerializable Interface

Implementing the ISerializable Interface allows the object to control the serialization process. we’ll soon see what that means, but it’s important to notice that you must also mark the class with the SerializableAttribute. Implementing the interface means, implementing two methods: GetObjectData to populate fields into the SerializationInfo, and another constructor which is called during deserialization to restore object state from the SerializationInfo.

[Serializable]
class MyClass : ISerializable
{
    public string FirstName { get; set; }         

    public MyClass() { }         

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("FirstName", FirstName);
    }         

    protected MyClass(SerializationInfo info, StreamingContext context)
    {
        FirstName = info.GetString("FirstName");
    }
}

Now Lets try to compare them by a few aspects

Inheritance - in both ways, derived classes must be marked with the SerializableAttribute (for the 1st choice, that’s all that needs to be done). However, if you implement the interface, the derived class would probably need to implement it too (don’t forget to also call the base class implementation). Another thing to remember is implementing the special constructor. It cannot be enforced by the compiler, so if you forget it- you’ll get a runtime exception “The constructor to deserialize an object of type … was not found.”!

Control – obviously implementing the interface give you full control. However if all you want to do is to leave some fields out of the serialization, just use the NonSerializedAttribute attribute. If you need more control, like performing some initialization code or validating the read values, use the ISerializable interface.

Performance – Option 1 uses Reflection. We know this is not the fastest way, however if your class contains only few primitive types the penalty is not so big. If you have more complicated collections you might consider serializing them yourself.

Versioning – If you add, remove or rename class fields, you will not be able to desirialize old saved object into a new one. to support this you will have to implement ISerializable.

In Summary, I am sure there are more aspects of Serialization which are not covered here, but my conclusion and also microsoft’s advice is – use the SerializableAttribute unless your have a good reason to implement the ISerializable Interface.

Tags :

9 Responses to “Is [Serializable] == ISerializable? No!”


  1. Cyril Gupta

    Said on April 22, 2008 :

    Hello,

    Thank you for the great article. I’ve never used the interface earlier. In fact I’ve only needed to use serialization about 3 times in my life. :)

  2. Niki

    Said on April 22, 2008 :

    Performance: Did you actually benchmark the two options? If so, which formatter did you use? Why didn’t you post the results?

    Are you sure that reflection is used during serialization? I always thought the serializer used Reflection.Emit to build the serialization code, so I don’t see why it should be a lot slower than hand-written serialization code.

    Versioning: This is simply not true. You can deserialize a type if there are unknown/missing fields, just use the OptionalFieldAttribute or the XmlSerializer’s events.

    Control: You should mention that you can inject code into the automatic serialization procedure as well using attributes.

  3. Shahar A

    Said on April 23, 2008 :

    Hi Niki,

    Benchmark was done using binary formatter, results will be posted later here.

    regarding reflection, from msdn http://msdn2.microsoft.com/en-us/library/ms979193.aspx :
    When you use the Serializable attribute, .NET run-time serialization uses reflection to identify the data that should be serialized.XML serialization uses reflection to generate special classes to perform the serialization

    please note that i wasn’t talking about XML serialization in this post…

    I missed the OptionalFieldAttribute. Thanks.

  4. James L

    Said on April 23, 2008 :

    I prefer to explicity implement ISerializable.GetObjectData so you don’t clutter MyClass

  5. idiotcoder

    Said on April 24, 2008 :

    You forgot the primary reason to use the interface, the ability to customize output. Sure, you have some ability with the attibutes, but you have a lot more flexibility when implementing the interface.

    That’s the reason I see it used the most.

  6. Sambasiva

    Said on February 3, 2011 :

    How we can use ISerializable and Iclone interfaces in Objects are drag and drop from parent panel to child panel……that objects are reference’s of parent panel to child panel….

    plz send details of this ……….
    bye
    samba

3 Trackback(s)

  1. Apr 23, 2008: Reflective Perspective - Chris Alcock » The Morning Brew #79
  2. Apr 23, 2008: Dew Drop - April 23, 2008 | Alvin Ashcraft's Morning Dew
  3. Jun 3, 2011: Binary Serialization | Monstersoft

Post a Comment