Unboxed Solutions Blog The frenetic soapbox

Jul 17

Sean

[XmlInclude] Rocks!

  • Created: Saturday, July 17, 2004
  • Sean

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

;