What Is the Point of the Iserializable Interface

What is the point of the ISerializable interface?

ISerializable is used to provide custom binary serialization, usually for BinaryFormatter (and perhaps for remoting purposes). Without it, it uses the fields, which can be:

  • inefficient; if there are fields that are only used for efficiency at runtime, but can be removed for serialization (for example, a dictionary may look different when serialized)
  • inefficient; as even for fields that are needed it needs to include a lot of additional metadata
  • invalid; if there are fields that cannot be serialized (such as event delegates, although they can be marked [NonSerialized])
  • brittle; your serialization is now bound to the field names - but fields are meant to be an implementation detail; see also Obfuscation, serialization and automatically implemented properties

By implementing ISerializable you can provide your own binary serialization mechanism. Note that the xml equivalent of this is IXmlSerializable, as used by XmlSerializer etc.

For DTO purposes, BinaryFormatter should be avoided - things like xml (via XmlSerializer or DataContractSerializer) or json are good, as are cross-platform formats like protocol buffers.

For completeness, protobuf-net does include hooks for ISerializable (allowing you to use a portable binary format without writing lots of code), but BinaryFormatter wouldn't be your first choice here anyway.

What is [Serializable] and when should I use it?

What is it?

When you create an object in a .Net framework application, you don't need to think about how the data is stored in memory. Because the .Net Framework takes care of that for you. However, if you want to store the contents of an object to a file, send an object to another process or transmit it across the network, you do have to think about how the object is represented because you will need to convert to a different format. This conversion is called SERIALIZATION.

Uses for Serialization

Serialization allows the developer to save the state of an object and recreate it as needed, providing storage of objects as well as data exchange. Through serialization, a developer can perform actions like sending the object to a remote application by means of a Web Service, passing an object from one domain to another, passing an object through a firewall as an XML string, or maintaining security or user-specific information across applications.

Apply SerializableAttribute to a type to indicate that instances of this type can be serialized. Apply the SerializableAttribute even if the class also implements the ISerializable interface to control the serialization process.

All the public and private fields in a type that are marked by the SerializableAttribute are serialized by default, unless the type implements the ISerializable interface to override the serialization process. The default serialization process excludes fields that are marked with NonSerializedAttribute. If a field of a serializable type contains a pointer, a handle, or some other data structure that is specific to a particular environment, and cannot be meaningfully reconstituted in a different environment, then you might want to apply NonSerializedAttribute to that field.

See MSDN for more details.

Edit 1

Any reason to not mark something as serializable

When transferring or saving data, you need to send or save only the required data. So there will be less transfer delays and storage issues. So you can opt out unnecessary chunk of data when serializing.

Is implementing ISerializable interface necessary when not implementing any custom serialization/deserialization

It's pretty pointless.

It could be justified if it had once implemented ISerializable for a better reason, and implementation changes meant that it was no longer as useful. It could be a breaking change to stop implementing it.

If they'd implemented it with an explicit implementation (void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) rather than public void GetObjectData(SerializationInfo info, StreamingContext context) and had the constructor that took SerializationInfo and StreamingContext private, then it'd be a less damaging change - still technically a breaking change but much less likely to actually break any real uses. This in itself is a reason for having that constructor private.

It must though be at least protected if the class isn't sealed, and derived classes must use it if they are to also be serialisable. In this case it's totally going to be a breaking change to stop using it as all derived classes would then be broken.

It would likewise be breaking change if you didn't implement it, and then started doing so, and had classes derived from it. This could be a justification for pre-empting the possibility, though to be honest I'd see that as a major failure of the YAGNI principle unless there was a very very good reason to suspect it would become useful. (Generally if you were going to add something that would make it necessary you could wrap whatever features required it in another class, implement it on that, and have a member of that type, so the existing class can still be serialised without it).

Edit: The "must" above is the "must" of "you must do this or there are bad implications" rather than the "must" of "you must do this or it won't compile". Of course, the former are worse than the latter because you can sometimes fail to do them.

What does the [Serializable] attribute do that ISerializable doesn't?

I thought you'd linked to Serializable, but you didn't:

All the public and private fields in a type that are marked by the SerializableAttribute are serialized by default, unless the type implements the ISerializable interface to override the serialization process.

and,

Apply the SerializableAttribute attribute even if the class also implements the ISerializable interface [...]

That is, the Serializable attribute indicates that this type can be serialized. ISerializable indicates that this type wants to control how this type is serialized.


Or, to put it another way, your question is phrased the wrong way around. SerializableAttribute should always be applied (to serializable classes), and is the "basic" level of serialization. ISerializable adds more (by allowing you to write code to control the process).

Implementing ISerializable unnecessary?

Serializable uses default serialization. The point of the ISerializable interface is to override serialization so that you can have your own.

When should we implement Serializable interface?

  1. From What's this "serialization" thing all about?:

    It lets you take an object or group of
    objects, put them on a disk or send
    them through a wire or wireless
    transport mechanism, then later,
    perhaps on another computer, reverse
    the process: resurrect the original
    object(s). The basic mechanisms are to
    flatten object(s) into a
    one-dimensional stream of bits, and to
    turn that stream of bits back into the
    original object(s).

    Like the Transporter on Star Trek,
    it's all about taking something
    complicated and turning it into a flat
    sequence of 1s and 0s, then taking
    that sequence of 1s and 0s (possibly
    at another place, possibly at another
    time) and reconstructing the original
    complicated "something."

    So, implement the Serializable interface when you need to store a copy of the object, send them to another process which runs on the same system or over the network.

  2. Because you want to store or send an object.

  3. It makes storing and sending objects easy. It has nothing to do with security.

Why are interfaces not [Serializable]?

Interfaces define a contract and do not have any state of their own.

Serialization is about saving and loading state into and out of an object model.

Not much point to serializing something that holds no state.


To answer the practical question of forcing an implementation of an interface to be Serializable - this is why the ISerializable interface exists.

In .NET you can declare an interface that should implement other interfaces:

interface MustBeSerializable : ISerializable {}

See some more information here.

OnSerializingAttribute vs ISerializable

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.

Why a class does not implement ISerializable interface violates MissingSerializationConstructorRule

Dictionary(TKey, TValue) implements ISerializable

[SerializableAttribute]
[ComVisibleAttribute(false)]
public class Dictionary<TKey, TValue> : IDictionary<TKey, TValue>,
ICollection<KeyValuePair<TKey, TValue>>, IDictionary, ICollection,
IReadOnlyDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>,
IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, ISerializable,
IDeserializationCallback


Related Topics



Leave a reply



Submit