Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of the ISerializable interface?

It seems like I can serialize classes that don't have that interface, so I am unclear on its purpose.

like image 248
leora Avatar asked May 01 '09 10:05

leora


People also ask

What is ISerializable interface in C#?

The ISerializable interface implies a constructor with the signature constructor (SerializationInfo information, StreamingContext context) . At deserialization time, the current constructor is called only after the data in the SerializationInfo has been deserialized by the formatter.

What is the purpose of serialization in C#?

Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, a database, or a file. Its main purpose is to save the state of an object in order to be able to recreate it when needed.

Why should I use serialization?

Well, serialization allows us to convert the state of an object into a byte stream, which then can be saved into a file on the local disk or sent over the network to any other machine. And deserialization allows us to reverse the process, which means reconverting the serialized byte stream to an object again.

Can we serialize interface C#?

When the serializer should serialize that object it knows that the object implements that interface, all it really has to do is serialize it and attach the type attribute (like it does if you serialize abstract classes or just super-classes in general).


2 Answers

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.

like image 199
Marc Gravell Avatar answered Sep 19 '22 16:09

Marc Gravell


Classes can be serialized in .NET in one of two ways:

  1. Marking the class with SerializableAttribute and decorating all the fields that you don't want to be serialized with the NonSerialized attribute. (As Marc Gravell points out, BinaryFormatter, which is the class typically used to format ISerializable objects, automatically serializes all fields unless they are specifically marked otherwise.)
  2. Implementing the ISerializable interface for fully custom serialization.

The former is simpler to use as it simply involves marking declarations with attributes, but is limited in its power. The latter allows more flexibility but takes significantly more effort to implement. Which one you should use depends completely on the context.

Regarding the latter (ISerializable) and it usage, I've quoted from the MSDN page for the interface:

Any class that might be serialized must be marked with the SerializableAttribute. If a class needs to control its serialization process, it can implement the ISerializable interface. The Formatter calls the GetObjectData at serialization time and populates the supplied SerializationInfo with all the data required to represent the object. The Formatter creates a SerializationInfo with the type of the object in the graph. Objects that need to send proxies for themselves can use the FullTypeName and AssemblyName methods on SerializationInfo to change the transmitted information.

In the case of class inheritance, it is possible to serialize a class that derives from a base class that implements ISerializable. In this case, the derived class should call the base class implementation of GetObjectData inside its implementation of GetObjectData. Otherwise, the data from the base class will not be serialized.

like image 34
Noldorin Avatar answered Sep 22 '22 16:09

Noldorin