如何创建一个可序列化的类,该类包含一组类中的一个类的实例

本文关键字:一个 实例 包含一 何创建 创建 序列化 | 更新日期: 2023-09-27 17:53:34

在。net 4或4.5中,如何设计一个可序列化的类,它包含一组类中的一个类的实例?例如,假设我有一个Garage类,它可以保存任何"车辆"类型类的实例,比如Car、Boat、Motorcycle、Motorhome。但是Garage只能保存其中一个类的实例。我已经尝试了几种不同的方法来做到这一点,但我的问题是使它可序列化。

下面是一个初始示例,其中Garage类中的实例只有一个选项。你应该可以直接把它插入一个新的控制台应用程序并尝试它。

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;
            }
        }
    }
}

如何创建一个可序列化的类,该类包含一组类中的一个类的实例

根据另一篇SO文章,这是最终为我工作的。它可以清晰地序列化和反序列化。使用这个例子,我可以设计一个对象的"树",它可以选择使用什么。因此,这可以扩展为一辆汽车可以有一个发动机的几个不同的发动机类型类和一个内饰的几个不同的内饰类型…等等。

代码通过添加如下语句开始工作:[XmlInclude(typeof(Car))]

但是如果有更好的方法请告诉我!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace Patterns
{
    public class Garage
    {
        private Vehicle _MyVehicle;
        public Garage()
        {
        }
        public string GarageOwner { get; set; }
        public Vehicle MyVehicle
        {
            get { return _MyVehicle; }
            set { _MyVehicle = value; }
        }
    }
    [XmlInclude(typeof(Car))]
    [XmlInclude(typeof(Boat))]
    [XmlInclude(typeof(Motorcycle))]
    [XmlInclude(typeof(Motorhome))]
    public abstract class Vehicle
    {
        public string VehicleType { get; set; }
        public int VehicleNumber { get; set; }
    }
    public class Car : Vehicle
    {
        public int Doors { get; set; }
    }
    public class Boat : Vehicle
    {
        public int Engines { get; set; }
    }
    public class Motorcycle : Vehicle
    {
        public int Wheels { get; set; }
    }
    public class Motorhome : Vehicle
    {
        public int Length { 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";
                Car c = new Car();
                c.VehicleType = "Lexus";
                c.VehicleNumber = 1234;
                c.Doors = 4;
                MyGarage.MyVehicle = c;
                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;
            }
        }
    }    
}

要序列化可序列化类的序列,可以使用泛型列表实例。

我生成这个

<?xml version="1.0"?>
<Garage xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <GarageOwner>John</GarageOwner>
  <MyVehicles>
    <Vehicle>
      <VehicleType>Car</VehicleType>
      <VehicleNumber>1234</VehicleNumber>
    </Vehicle>
    <Vehicle>
      <VehicleType>Boat</VehicleType>
      <VehicleNumber>56234</VehicleNumber>
    </Vehicle>
  </MyVehicles>
</Garage>

通过简单地将MyVehicle转换为一个通用列表

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
namespace Patterns
{
    [Serializable()]
    public class Garage
    {
        public string GarageOwner { get; set; }
        public List<Vehicle> MyVehicles { get; set; }
    }
    [Serializable()]
    public class Vehicle
    {
        public string VehicleType { get; set; }
        public int VehicleNumber { get; set; }
    }
    class Serializer
    {
        static string _StartupPath = @"C:'temp'";
        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";
                // Create some vehicles
                var myVehicle1 = new Vehicle();
                myVehicle1.VehicleType = "Car";
                myVehicle1.VehicleNumber = 1234;
                var myVehicle2 = new Vehicle();
                myVehicle2.VehicleType = "Boat";
                myVehicle2.VehicleNumber = 56234;
                // Create a new instance and add the vehicles
                MyGarage.MyVehicles = new List<Vehicle>()
                {
                    myVehicle1, 
                    myVehicle2
                };
                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;
            }
        }
    }
}