我有一个包含接口成员变量的类。如何反序列化此类
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>
答案 0 :(得分:1)
假设您使用XmlSerializer
,序列化和反序列化都需要进行两项更改:
Sensor
继承的类型。List<ISensor>
替换为List<Sensor>
。不幸的是,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>