反序列化带有接口的类
本文关键字:接口 反序列化 | 更新日期: 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
,那么序列化和反序列化都需要进行两个更改:
- 告诉序列化程序可以出现的类型列表,换句话说,从
Sensor
继承的类型。 - 用类代替接口,即用
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>