C# Xml序列化Dictionary类

小柊 发表于 2017年09月16日 17时57分37秒

一、扯淡背景

本人一直有个习惯就是开发的时候把一些程序需要使用的后期可能会变动的配置做成Xml写到本地文件里,当每次程序启动的时候再读取出来,以免因为配置变动导致重新修改代码。

最近的一次更新调整中,需要在配置类中加入字典类Dictionary<TKey, TValue>。

结果不加不要紧,一加这个字典类,在序列化为Xml的时候直接抛出了异常:

 

上网搜了一下,发现这个问题非常普遍。解决办法有一堆,但具体原因并不清楚。

本人去简单的翻了一下.net的源码实现,发现.net在初始化XmlSerializer的时候会进行类型检查,如果发现传入的类型实现了IDictionary接口,就会抛出NotSupportedException异常:

 

二、解决方案

虽然不知道微软为什么明令禁止实现了IDictionary的类进行Xml序列化和反序列化,但这个问题也有解决的方法,那就是创建一个新的类,继承Dictionary<TKey, TValue>类的同时实现IXmlSerializable接口。在这里我将新建的类名命名为:DictionaryEx,具体的代码如下:

 

三、代码解释

上面代码其实并不复杂,首先我们继承了Dictionary<TKey, TValue>类,所以我们需要根据Dictionary<TKey, TValue>类的构造函数,写出对应的构造函数。

然后就是实现IXmlSerializable接口。IXmlSerializable接口要求实现这三个方法:

 

首先XmlSchema GetSchema();这个方法是一个保留方法,根据MSDN的要求,直接返回null。

然后是void WriteXml(XmlWriter writer);方法,这个方法将在此类被Xml序列化时被调用,负责将当前对象写入XmlWriter中。所以在此方法里我们使用foreach遍历当前字典类中的所有键,将键和值序列化后写入XmlWriter中。

最后就是void ReadXml(XmlReader reader); 了。这个方法将在Xml文件被反序列化时被序列器调用,负责将Xml文件中的对应节点一一返回。

 

四、实际运行展示

测试用的可Xml序列化字典类及数据:

 

序列化结果:

 

从文件加载并反序列化Xml,输出字典内容:

 

运行结果:

 

1.DictionaryEx:链接:http://pan.baidu.com/s/1nvtA5Xf 密码:irqx

2.XmlHelper(Xml序列化及反序列化辅助类):链接:http://pan.baidu.com/s/1sl5DCHR 密码:5kif

 

 

 

 

小柊

2017年9月16日 17:49:33

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注