Recently was working on a small project that required me to store a collection of objects. So I figured I would refresh my knowledge of the serialization available in C#.
First I had a look at the XmlSerializer. First you need to define an object to serialize.
[Serializable, XmlRoot(Namespace = "http://rabiddog.co.za")]
public class Dog
{
public Dog(String name, int age)
{
this.Name = name;
this.Age = age;
}
public string Name { get; set; }
public int Age { get; set; }
//The XmlSerializer requires a default Constructor
public Dog() { }
}
Now that we have the class defined, lets create a collection and serialize that collection to an XML file. Create a console application and then add the following method
private static void XmlSerialize()
{
Dog dog1 = new Dog("Charlie", 42);
Dog dog2 = new Dog("Jim", 32);
List<Dog> myDogs = new List<Dog>{dog1, dog2};
using (Stream stream = new FileStream("MyDogs.xml", FileMode.Create, FileAccess.Write, FileShare.None))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[]{typeof(Dog)});
xmlSerializer.Serialize(stream, myDogs);
}
}
Then call the method from the Main() function, let it run and you should end up with a file called MyDogs.xml in the debug/bin directory. The file should look something like this
<?xml version="1.0"?>
<ArrayOfDog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Dog>
<Name xmlns="http://rabiddog.co.za">Charlie</Name>
<Age xmlns="http://rabiddog.co.za">42</Age>
</Dog>
<Dog>
<Name xmlns="http://rabiddog.co.za">Jim</Name>
<Age xmlns="http://rabiddog.co.za">32</Age>
</Dog>
</ArrayOfDog>
Well that was pretty simple. All we had to do was add the [Serializable] annotation to the class and then create an instance of XmlSerializer to write it to. You could also set the properties to be attributes by decorating them with the [XmlAttribute] annotation.
Cool, lets move onto the binary serialization shall we? Using the same Dog class we are going to serialize this down to a binary file.
We do that by changing the serializer we are using to the BinaryFormatter:
private static void BinarySerialize()
{
Dog dog1 = new Dog("Charlie", 42);
Dog dog2 = new Dog("Jim", 32);
List<Dog> myDogs = new List<Dog> { dog1, dog2 };
BinaryFormatter formatter = new BinaryFormatter();
using (Stream stream = new FileStream("MyDogs.dat", FileMode.Create, FileAccess.Write, FileShare.None))
{
formatter.Serialize(stream, myDogs);
}
}
Don’t forget to call this method from the Main method. This should produce a MyDogs.dat file in the debug/bin directory. Happy days but there is just one problem. What good is it serializing it if we can deserialize it?
First lets deserialize our XML like so
private static void XmlDeserialize()
{
using (Stream stream = new FileStream("MyDogs.xml", FileMode.Open, FileAccess.Read))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[] { typeof(Dog) });
List<Dog> myDogs = (List<Dog>)xmlSerializer.Deserialize(stream);
foreach(Dog dog in myDogs)
{
Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
}
}
}
And the method to deserialize our binary file would be something along the lines of
private static void BinaryDeserialize()
{
BinaryFormatter formatter = new BinaryFormatter();
using (Stream stream = new FileStream("MyDogs.dat", FileMode.Open, FileAccess.Read))
{
List<Dog> myDogs = (List<Dog>)formatter.Deserialize(stream);
foreach (Dog dog in myDogs)
{
Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
}
}
}
It thought this was a particularly neat way of storing data on application close. Serialize your object graphs and exit. When you start the application deserialize back to the original state and off you go. No over head of setting up database connections or any other mechanisms of persistence.
Yes I know it is old school but is facilitates the requirements for the application I am using. The reason I raise it is because we far to often get caught up in distributed application mentality when something simple like this would do just fine! Below is the enter class file. I hope some one found this useful 
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
namespace RabidDog
{
class Program
{
private static void XmlSerialize()
{
Dog dog1 = new Dog("Charlie", 42);
Dog dog2 = new Dog("Jim", 32);
List<Dog> myDogs = new List<Dog>{dog1, dog2};
using (Stream stream = new FileStream("MyDogs.xml", FileMode.Create, FileAccess.Write, FileShare.None))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[]{typeof(Dog)});
xmlSerializer.Serialize(stream, myDogs);
}
}
private static void XmlDeserialize()
{
using (Stream stream = new FileStream("MyDogs.xml", FileMode.Open, FileAccess.Read))
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Dog>), new Type[] { typeof(Dog) });
List<Dog> myDogs = (List<Dog>)xmlSerializer.Deserialize(stream);
foreach(Dog dog in myDogs)
{
Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
}
}
}
private static void BinarySerialize()
{
Dog dog1 = new Dog("Charlie", 42);
Dog dog2 = new Dog("Jim", 32);
List<Dog> myDogs = new List<Dog> { dog1, dog2 };
BinaryFormatter formatter = new BinaryFormatter();
using (Stream stream = new FileStream("MyDogs.dat", FileMode.Create, FileAccess.Write, FileShare.None))
{
formatter.Serialize(stream, myDogs);
}
}
private static void BinaryDeserialize()
{
BinaryFormatter formatter = new BinaryFormatter();
using (Stream stream = new FileStream("MyDogs.dat", FileMode.Open, FileAccess.Read))
{
List<Dog> myDogs = (List<Dog>)formatter.Deserialize(stream);
foreach (Dog dog in myDogs)
{
Console.WriteLine("My Dog {0} is {1} years old", dog.Name, dog.Age);
}
}
}
static void Main(string[] args)
{
XmlSerialize();
BinarySerialize();
XmlDeserialize();
BinaryDeserialize();
}
}
[Serializable, XmlRoot(Namespace = "http://rabiddog.co.za")]
public class Dog
{
public Dog(String name, int age)
{
this.Name = name;
this.Age = age;
}
public string Name { get; set; }
public int Age { get; set; }
//The XmlSerializer requires a default Constructor
public Dog() { }
}
}