使用接口反序列化类

时间:2013-01-01 06:51:48

标签: c# serialization

我有一个包含接口成员变量的类。如何反序列化此类

interface ISensor { }

[Serializable]
class Sensor: ISensor { }

[Serializable]
class Root
{
    [XmlElement("Sensor")]
    public List<ISensor> SensorList{ get; set; }
}

我的XML将是这样的

  <?xml version="1.0" encoding="us-ascii"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Sensor >
        <SensorName>Name1</SensorName>
        <SensorValue>0.0</SensorValue>
    </Sensor>
    <Sensor>
        <SensorName>Name2</SensorName>
        <SensorValue>148.00</SensorValue>
    </Sensor>
</Root>

1 个答案:

答案 0 :(得分:1)

假设您使用XmlSerializer,序列化和反序列化都需要进行两项更改:

  1. 告诉序列化程序可以显示的类型列表,换句话说,是从Sensor继承的类型。
  2. 使用List而不是接口的类,换句话说,将List<ISensor>替换为List<Sensor>
  3. 不幸的是,XmlSerializer无法以您希望的方式处理接口。有关详细信息,请参阅XmlSerializer serialize generic List of interface

    如果不能使用基类您可以通过实现IXmlSerializable来编写自己的XML序列化程序。覆盖ReadXml并手动解析XML。

    例如:

    public interface ISensor { }
    
    [Serializable]
    public class Sensor : ISensor { }
    
    [Serializable]
    public class Root
    {
        // Changed List<ISensor> to List<Sensor>. I also changed
        // XmlElement to XmlArray so it would appear around the list.       
        [XmlArray("Sensor")]
        public List<Sensor> SensorList { get; set; }
    }
    
    [Serializable]
    public class SensorA : Sensor
    {
        [XmlElement("A")]
        public string A { get; set; }
    }
    
    [Serializable]
    public class SensorB : Sensor
    {
        [XmlElement("B")]
        public string B { get; set; }
    }
    
    class Program
    {
        public static void Main(string[] args)
        {
            XmlSerializer xmlSerializer;
    
            Root root = new Root();
            root.SensorList = new List<Sensor>();
            root.SensorList.Add(new SensorA() {A = "foo"});
            root.SensorList.Add(new SensorB() {B = "bar"});
    
            // Tell the serializer about derived types
            xmlSerializer = new XmlSerializer(typeof (Root), 
                new Type[]{typeof (SensorA), typeof(SensorB)});
            StringBuilder stringBuilder = new StringBuilder();
            using (StringWriter stringWriter = new StringWriter(stringBuilder))
            {
                xmlSerializer.Serialize(stringWriter, root);
            }
    
            // Output the serialized XML
            Console.WriteLine(stringBuilder.ToString());
    
            Root root2;
            using (StringReader stringReader = new StringReader(stringBuilder.ToString()))
            {
                root2 = (Root) xmlSerializer.Deserialize(stringReader);
            }
        }
    }
    

    Console.WriteLine语句的输出为:

    <?xml version="1.0" encoding="utf-16"?>
    <Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Sensor>
        <Sensor xsi:type="SensorA">
          <A>foo</A>
        </Sensor>
        <Sensor xsi:type="SensorB">
          <B>bar</B>
        </Sensor>
      </Sensor>
    </Root>