Serialization is the process of writing data out in a storage medium in a pre-defined format so that it can be read back programmatically. Even though there can be many forms of Serialization (even usage of databases is Serialization in some sense), in most cases, serialization is used to persist the program state onto a file and read it back so that computation can proceed from an intermediate state.
I remember at one point of time, I used to fret and worry about having to decide a format to write my data in, and then write procedures for writing them out into a file and then reading them back. And then look for minute bugs which crop up in this process. Developer productivity goes for a six while the manager manages a sinister laugh in the sidelines as the employee sweats it out with printf and scanf.
No more! Thankfully there is something called object serialization that comes to our rescue. With the dawn of languages such as Java and the .NET platform, serialization was made very simple, in fact so simple that little cherubs (in their garden playing harps or rather System.IO.Harp) could just add a single attribute to the class name and all the perspiration is taken care of by the framework.
In the .NET framework, serialization can be very simply implemented by adding the [Serializable] attribute to the class. Any fields that one doesn’t want to be serialized can be marked with a [NonSerialized] attribute. Thereafter, you just use a BinaryFormatter to format data into a suitable binary format, open a FileStream to write it out to a file, and bingo, you’re done!
However, I was not convinced it could be so easy. The objects typically form a graph structure and might be cyclical. Would the automatic implementation of .NET Serialization be able to handle this cyclical structure, or would I need to fish DFS and BFS from my old dusty textbooks, parse them in an acyclic manner and write them in a suitable order. All my worries were misplaced! It just works… it’s magical. You can be a dork and use the object serialization in .NET!
There is a small catch though. Static fields of a class are not serialized automatically (among some other gotchas). And you need to implement the ISerializable interface and provide custom implementations of the GetObjectData method and a constructor of the class which takes SerializationInfo as a parameter (See some examples here) in order to deal with these special cases. In my simple case, I had an identifier for every object which I allocated based on a idCount variable which was a static integer. Hence, in the custom constructor, I set the value of the idCount to the highest id value I had seen so far during deserialization so that I don’t generate old id values gain.
id = info.GetInt32(“id”);
if ((this.id + 1) > idCount)
idCount = (this.id + 1);
But still, object serialization is a great boon for most of us developers who don’t wish to tear their hair out trying to write code that is not even important for their work!
Ok. So, I discovered that in case you override the Serialization using the ISerializable interface, you need to override it for all the derived classes. A lot of hard work I am not willing to do. Another trick could be that in case of the base class, instead of implementing the ISerializable interface, implement the IDeserializationCallback, which essentially lets you override the OnDeserialization method which is called after the deserialization is done, and you can write custom logic there to populate the static or the Non-Serialized fields.