Serialization is the process of converting a graph of objects, located in memory, into a linear sequence of bytes. That sequence of bytes can be sent elsewhere (for example, to a remote computer) and Deserialized, thereby making an exact clone in that remote memory of the original graph of objects.
Because the runtime metadata 'knows' all there is to know about each object's layout in memory, its field and property definitions, you can serialize objects automatically, without having to write code to serialize each field.
The serialized stream might be encoded using XML, or a compact binary representation. The format is decided by the the Formatter object that you call. Pluggable formatters allow the developer to serialize objects in with the two supplied formats (binary and SOAP) or create their own. Below is an example of how to perform default Serialization of a graph of objects, whose root is the arraylist l. This code serializes the graph to a FileStream:
class SerializeExample{ public static void Main(String[] args) { ArrayList l = new ArrayList(); for (int x=0; x< 100; x++) { l.Add (x); } // create the object graph FileStream s = File.Create("foo.bin"); // create the filestream BinaryFormatter b = new BinaryFormatter(); // create the BinaryFormatter b.Serialize(s, l); // serialize the graph to the stream } // end main } // end class
This next code then goes on to creates a clone of the graph by deserializing it. The root of the clone graph is called p:
using System; using System.IO; using System.Collections; using System.Serialization; using System.Serialization.Formatters.Binary; class DeSerialize{ public static void Main(String[] args) { FileStream s = File.Open("foo.bin"); // open the filestream BinaryFormatter b = new BinaryFormatter(); // create the formatter ArrayList p = (ArrayList) b.Deserialize(s); // deserialize p.ToString(); // print out the new object graph } // end Main } // end Class DeSerialize
Serializetion can take place with any stream, not just a FileStream (see MemoryStream, NetStream, etc.)
Serialization makes use of several classes, as follows:
Each of these components is 'pluggable' -- the programmer can provide alternatives.
If a class author wishes to take special action when objects of that class are serialized and deserialized, he can choose to implement the ISerializable interface. This allows full control. For example, the author may define his own, custom SerializationInfo, to describe parts of the object, or synthesized fields that capture the object state for serialization. If a class implements ISerializable, that interface will always be called in preference to default serialization. The ISerializable interface is only contains one method:
void GetObjectData (SerializationInfo info, StreamingContext context); And an implied constructor that may be private. private <TypeName> (SerializationInfo info, StreamingContext)
An important note on deserialization is that we return the fields in the same order in which they are returned from Reflection. Reflection makes no guarantee that it will follow metadata ordering.