It seems like I can serialize classes that don't have that interface, so I am unclear on its purpose.
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.
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.
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.
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).
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:
[NonSerialized]
)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.
Classes can be serialized in .NET in one of two ways:
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.)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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With