【发布时间】:2017-04-28 17:34:40
【问题描述】:
例如,我有以下课程:
public abstract class Device
{
}
public class WindowsDevice: Device
{
}
public class AndroidDevice: Device
{
}
现在我想将 WindowsDevice 和 AndroidDevice 序列化/反序列化为 XML:
public static string Serialize(object o, Type[] additionalTypes = null)
{
var serializer = new XmlSerializer(o.GetType(), additionalTypes);
using (var stringWriter = new StringWriterWithEncoding(Encoding.UTF8))
{
serializer.Serialize(stringWriter, o);
return stringWriter.ToString();
}
}
这将产生以下输出:
<?xml version="1.0" encoding="utf-8"?>
<WindowsDevice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
</WindowsDevice>
但现在我无法反序列化它,因为在我的应用程序中我不知道 XML 是 WindowsDevice 还是 AndroidDevice,所以我必须反序列化为 typeof(Device)。但随后我会得到一个异常,即“WindowsDevice”在 XML 中是意外的。
我尝试了 XmlInclude 和 extraTypes,但没有成功。
我不明白的是,如果我有以下示例类:
public class SampleClass
{
public List<Device> Devices {get;set}
}
如果我序列化 SampleClass 并使用 XmlInclude 或 extraTypes 我完全得到我想要的:
<Devices>
<Device xsi:type="WindowsDevice"></Device>
</Devices>
但我没有那个类,也没有设备列表。我只想序列化/反序列化 WindowsDevice 和 AndroidDevice 但在反序列化时我不知道它是 AndroidDevice 还是 WindowsDevice 所以我必须使用 typeof(Device) 并希望获得正确的子类 AndroidDevice 或 WindowsDevice,所以而不是:
<WindowsDevice></WindowsDevice>
我想拥有:
<Device xsi:type="WindowsDevice"></Device>
如何做到这一点?
【问题讨论】:
-
开始标签没有告诉你你需要知道什么吗?
告诉您对象是什么。难道你不能只是阅读那个标签然后你就知道它是什么类型了吗? -
我有很多这样的类和一个通用的序列化/反序列化方法。我不想使用这种“肮脏”的解决方法。考虑重命名一个类,添加新类等。如果可能的话,我更喜欢一个干净的解决方案。如前所述,如果我使用 List,XmlSerializer 能够做我想做的事,所以我想知道如何在一个类的单个实例上使用该机制。
-
我尝试了 XmlInclude 和 extraTypes 但没有成功。 - 你尝试了什么?我认为它应该有效。
-
@dbc: [XmlInclude(typeof(WindowsDevice)] public abstract class Device { } And: new XmlSerializer(o.GetType(), new Type[] { typeof(WindowsDevice})
标签: c# xml serialization