Serialization can be defined as the process of storing the state of an object to a storage medium. During this process, the public and private fields of the object and the name of the class, including the assembly containing the class, are converted to a stream of bytes, which is then written to a data stream. When the object is subsequently deserialized, an exact clone of the original object is created.
When implementing a serialization mechanism in an object-oriented environment, you have to make a number of tradeoffs between ease of use and flexibility. The process can be automated to a large extent, provided you are given sufficient control over the process. For example, situations may arise where simple binary serialization is not sufficient, or there might be a specific reason to decide which fields in a class need to be serialized. The following sections examine the robust serialization mechanism provided with the .NET Framework and highlight a number of important features that allow you to customize the process to meet your needs.
Consider the following class, BookMark, which is used to stored information about web addresses and their descriptions.
Public Class BookMark
Private pURL As String
Private pDescription As String
Private pNextURL As BookMark
Private dateCreated As Date
dateCreated = Now
Public Sub printIndex()
pURL = Value
pDescription = Value
pNextURL = Value
The BookMark class contains properties as well as private variables. The NextURL property is used to link up multiple BookMark objects, much like a linked list.
Let’s create two BookMark objects and link them up:
Dim BM1 As New BookMark
Dim BM2 As New BookMark
BM1.URL = “http://www.amazon.com”
BM1.Description = “Amazon.com Web site”
BM1.NextURL = BM2
BM2.URL = “http://www.oreilly.com”
BM2.Description = “O’Reilly Web Site”
BM2.NextURL = Nothing
I will serialize the objects into a binary stream by writing the Serialize() function:
Function Serialize(ByVal BkMk As BookMark) _
Dim ms As New MemoryStream
Dim fs As New FileStream(“c:\BookMarks.dat”, _
Dim formatter As New BinaryFormatter
‘ serialize to memory stream
‘ serialize to file stream
ms.Position = 0
Before you serialize an object, you need to prefix the class name with the <Serializable()> attribute:
<Serializable()> Public Class BookMark
I used the BinaryFormatter class from the System.Runtime.Serialization.Formatters.Binary namespace to serialize the BookMark object into a memory stream, as well as into a file stream. The function then returns a memory stream object representing the serialized BookMark object.
‘—serializing an object graph into a memory stream
Dim ms As MemoryStream = Serialize(BM1)
To prove that the object is serialized correctly, I will de-serialize the memory stream and assign it back to a BookMark object:
‘—deserializing a memory stream into an object graph
Dim newBM As BookMark
newBM = Deserialize(ms)
Here is the DeSerialize() function:
Function Deserialize(ByVal ms As MemoryStream) _
Dim formatter As New BinaryFormatter
To display the values of the de-serialized BookMark object, I use the Print() subroutine:
Sub Print(ByVal BM As BookMark)
Console.WriteLine(BM.URL.ToString & ” – ” & BM.Description)
BM = BM.NextURL
Loop Until BM Is Nothing
You should see the following in the output window:
9/29/2003 1:11:47 AM
http://www.amazon.com – Amazon.com Web site
9/29/2003 1:12:06 AM
http://www.oreilly.com – O’Reilly Web Site
But how does the binary stream look like? To answer this question, let’s take a look at the c:\BookMarks.dat file that we have created in the process.
To view the binary file, simply drag-and-drop it onto Visual Studio .NET. You should see something similar to what is shown in Figure 1:
A few observations are worth noting at this point:
- Private variables and properties are all serialized. In binary serialization, both the private variables and properties are serialized. This is known as deep serialization, as opposed to shallow serialization in XML serialization (which only serializes the public variables and properties). I will discuss XML serialization in the next article.
- Object graphs are serialized. In our example, two BookMark objects are linked, and the serialization process takes care of the relationships between the two objects.
There are times that you do not want to serialize all of the data in your object. For example, if you do not wish to persist the date and time that the BookMark objects have been created, you can prefix the variable name (that you do not wish to serialize) with the <NonSerialized()> attribute:
<NonSerialized()> Private dateCreated As Date
The dateCreated variable will not be serialized.