title: How to make a serializable class that contains an instance of one class from a set of classes
body: <p>In .Net 4 or 4.5, how would you design a serializable class that contains an instance of one class from a set of classes? For instance, suppose I have a Garage class, which can hold an instance of any "vehicle" type classes, say Car, Boat, Motorcycle, Motorhome. But the Garage can only hold an instance of one of those classes. I have tried a few different ways of doing this, but my problem is to make it serializable.</p>
  
  <p>Here is a starting example where there is only one option for the instance in the Garage class. You should be able to plug it right into a new console app and try it.</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.IO;
  using System.Xml;
  using System.Xml.Serialization;
  
  namespace Patterns
  {
      [Serializable()]
      public class Garage
      {
          private Vehicle _MyVehicle;
  
          public Garage()
          {
          }
          public string GarageOwner { get; set; }
          public Vehicle MyVehicle
          {
              get { return _MyVehicle; }
              set { _MyVehicle = value; }
          }
      }
  
      [Serializable()]
      public class Vehicle
      {
          public string VehicleType { get; set; }
          public int VehicleNumber { get; set; }
      }
  
      class Serializer
      {
          static string _StartupPath = @"C:\Projects\Patterns\Data\";
          static string _StartupFile = "SerializerTest.xml";
          static string _StartupXML = _StartupPath + _StartupFile;
  
          static void Main(string[] args)
          {
              Console.Write("Press w for write. Press r for read:");
              ConsoleKeyInfo cki = Console.ReadKey(true);
              Console.WriteLine("Pressed: " + cki.KeyChar.ToString());
              if (cki.KeyChar.ToString() == "w")
              {
                  Garage MyGarage = new Garage();
                  MyGarage.GarageOwner = "John";
                  MyGarage.MyVehicle = new Vehicle();
                  MyGarage.MyVehicle.VehicleType = "Car";
                  MyGarage.MyVehicle.VehicleNumber = 1234;
                  WriteGarageXML(MyGarage);
                  Console.WriteLine("Serialized");
              }
              else if (cki.KeyChar.ToString() == "r")
              {
                  Garage MyGarage = ReadGarageXML();
                  Console.WriteLine("Deserialized Garage owned by " +  MyGarage.GarageOwner);
              }
              Console.ReadKey();
          }
          public static void WriteGarageXML(Garage pInstance)
          {
              XmlSerializer writer = new XmlSerializer(typeof(Garage));
              using (FileStream file = File.OpenWrite(_StartupXML))
              {
                  writer.Serialize(file, pInstance);
              }
          }
          public static Garage ReadGarageXML()
          {
              XmlSerializer reader = new XmlSerializer(typeof(Garage));
              using (FileStream input = File.OpenRead(_StartupXML))
              {
                  return reader.Deserialize(input) as Garage;
              }
          }
      }
  }
  </code></pre>