If you want to serialize a set of related objects in an “is a” relationship, the XmlInclude attribute on the base class comes in handy. In my example, I want to serialize all three classes: Automobile, Car, and Truck using the same code. Same with deserializing. Later, I will worry about casting to the correct type. Here's what I came up with - thought I'd share.
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Xml.Serialization;
using System.IO;
using System.Text;
[System.Xml.Serialization.XmlInclude(typeof(Car))]
[System.Xml.Serialization.XmlInclude(typeof(Truck))]
public class Automobile
{
public string Name;
public int Year;
}
public class Car : Automobile
{
public int NumerOfDoors;
}
public class Truck : Automobile
{
public bool LongBed;
}
class App
{
static string Serialize(Automobile vehicle)
{
XmlSerializer ser = new XmlSerializer(typeof(Automobile));
StringBuilder sb = new StringBuilder();
TextWriter writer = new StringWriter(sb);
ser.Serialize(writer, vehicle);
return sb.ToString();
}
static Automobile DeSerialize(string data)
{
XmlSerializer ser = new XmlSerializer(typeof(Automobile));
TextReader reader = new StringReader(data);
return (Automobile) ser.Deserialize(reader);
}
[STAThread]
static void Main(string[] args)
{
StringCollection vehicles = new StringCollection();
Automobile a = new Automobile();
a.Name = "Just an automobile";
a.Year = 1967;
vehicles.Add(Serialize(a));
Car c = new Car();
c.Name = "Hyundai";
c.Year = 2002;
c.NumerOfDoors = 4;
vehicles.Add(Serialize(c));
Truck t = new Truck();
t.Name = "Ram";
t.Year = 1999;
t.LongBed = false;
vehicles.Add(Serialize(t));
foreach(string serializedVehicle in vehicles)
{
Automobile auto = DeSerialize(serializedVehicle);
Console.WriteLine("The type of this automobile is: {0}", auto.GetType());
if(auto is Car)
{
Car car = (Car) auto;
Console.WriteLine("car name = {0}, year={1}, doors={2}",
car.Name, car.Year, car.NumerOfDoors);
}
else if(auto is Truck)
{
Truck truck = (Truck) auto;
Console.WriteLine("Truck name={0}, year={1}, longbed={2}", truck.Name, truck.Year, truck.LongBed);
}
else
{
Console.WriteLine("Plain ol' automobile: name={0}, year={1}", auto.Name, auto.Year);
}
}
}
}
Results:
The type of this automobile is: Automobile
Plain ol' automobile: name=Just an automobile, year=1967
The type of this automobile is: Car
car name = Hyundai, year=2002, doors=4
The type of this automobile is: Truck
Truck name=Ram, year=1999, longbed=False
Press any key to continue