Serialization – Part 1 – Binary Serializer

Serialization is the process of transforming an in-memory object or an object graph into a stream of bytes or text. Deserialization is the opposite process of transforming a stream of bytes or text into an in-memory object or object graph.

.Net framework offers three serialization “engines”:

  • Binary serializer
  • Data contract serializer
  • XML serializer

Binary serializer

In order to create serializable types using binary serializer engine there are two options:

  • annotate the type with [SerializableAttribute] from namespace System
  • implement the ISerializabe interface from System.Runtime.Serialization namespace (this should be done when more control is required over serialization process, for example when one need to encrypt/decrypt a field of the object that is serialized/deserialized)

The binary serializer is fast, but its drawback is that it is tightly coupled withe the internal structure of the types. The binary serializer is primarily designed to produce binary data, but .Net offers formatters to produce XML as well.

.Net Remoting uses the binary serialization engine.

In the example below three types (Persons, Person and Address) are create and annotated with [SerializableAttribute]. A single instance of Address is created and it will be assigned to two different Person-s. An interesting aspect of the binary serialization is that the referential equality of the Address object will be preserved after serialization and deserialization:

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
 
namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var address = new Address
            {
                City = "Timisoara",
            };
 
            var persons = new Persons
            {
                M = new Person
                {
                    Name = "John",
                    Address = address,
                },
                F = new Person
                {
                    Name = "Jane",
                    Address = address,
                }
            };
 
            TestBinaryFormatter(persons);
        }
 
        static void TestBinaryFormatter(Persons persons)
        {
            Print("Before Serialization:", persons);
 
            IFormatter formatter = new BinaryFormatter();
            using (Stream stream = new MemoryStream())
            {
                formatter.Serialize(stream, persons);
                stream.Position = 0;
                Persons newPersons = (Persons)formatter.Deserialize(stream);
                Print("After Serialization: ", newPersons);
            }
        }
 
        static string ReferenceEquals(Address a1, Address a2)
        {
            return object.ReferenceEquals(a1, a2) ?
                "[== References to address objects are equal]" :
                "[!= References to address objects are NOT equal]";
        }
 
        static void Print(string message, Persons persons)
        {
            Console.WriteLine("{0} {1} {2}", 
                message,
                persons, 
                ReferenceEquals(persons.M.Address, persons.F.Address));
        }
    }
 
    [Serializable]
    public class Persons
    {
        public Person M { get; set; }
        public Person F { get; set; }
 
        public override string ToString()
        {
            return string.Format("[{0}] & [{1}]", M, F);
        }
    }
 
    [Serializable]
    public class Person
    {
        public string Name { get; set; }
        public Address Address { get; set; }
 
        public override string ToString()
        {
            return string.Format("{0} - {1}", Name, Address);
        }
    }
 
    [Serializable]
    public class Address
    {
        public string City { get; set; }
 
        public override string ToString()
        {
            return string.Format("{0}", City);
        }
    }
}

 

The output is:

Before Serialization: [John - Timisoara] & [Jane - Timisoara] [== References to address objects are equal]
After Serialization: [John - Timisoara] & [Jane - Timisoara] [== References to address objects are equal]
Press any key to continue . . .

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s