反序列化带有接口的类

本文关键字:接口 反序列化 | 更新日期: 2023-09-27 17:50:22

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

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>

反序列化带有接口的类

假设您使用的是XmlSerializer,那么序列化和反序列化都需要进行两个更改:

  1. 告诉序列化程序可以出现的类型列表,换句话说,从Sensor继承的类型。
  2. 用类代替接口,即用List<ISensor>代替List<Sensor>

不幸的是,XmlSerializer不能以您想要的方式处理接口。有关更多信息,请参阅XmlSerializer序列化接口的泛型列表。

如果不能使用基类,你可以通过实现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);
        }
    }
}

控制台的输出。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>