反序列化为List时的XmlRootAttribute放置
我有以下XML
TWTR
twitter.com FB
facebook.com SO
stackoverflow.com
这是代码:
public class Program { static void Main(string[] args) { var fs = new FileStream(@"D:\temp\Sites.xml", FileMode.Open); var serializer = new XmlSerializer(typeof(List)); var instance = (List)serializer.Deserialize(fs); } } [XmlRoot("Sites")] public class Site { public string Code { get; set; } public string Name { get; set; } }
我得到的例外是: was not expected.
。 当我没有为XmlSerializer
定义XmlRoot时,通常会出现此错误的原因。 但正如您所看到的,我通过使用XmlRootAttribute
修饰类Site
来实现这XmlRootAttribute
为了完成我的困惑,以下技巧有效:
更换
var serializer = new XmlSerializer(typeof(List));
同
var serializer = new XmlSerializer(typeof(List), new XmlRootAttribute("Sites"));
我错过了什么吗?
未使用添加到Site
的XmlRoot
属性,因为您没有反序列化Site
类型的对象。 您正在反序列化List
类型的对象,这是序列化程序查找XmlRoot
属性的位置。
您的解决方法实际上是正确的解决方案。 但是,如果您经常在程序中执行此反序列化,请确保缓存XmlSerializer
实例,因为该特定构造函数不会在内部缓存动态生成的程序集 – 这与您通常使用的构造函数形成对比。
如果您可以控制XML,那么只需更改:
至
如果您无法控制XML,请创建自己的集合并反序列化。
[XmlRoot("Sites")] public class Sites : List { }
使用以下构造函数时要小心:
var serializer = new XmlSerializer(typeof(List), new XmlRootAttribute("Sites"));
正如微软在这里指出的那样,如果你没有缓存与List
相关的序列化程序的实例,你最终会泄漏内存……
动态生成的程序集
为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定的类型。 基础结构查找并重用这些程序集。 仅当使用以下构造函数时,才会出现此问题:
XmlSerializer.XmlSerializer(类型)
XmlSerializer.XmlSerializer(Type,String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,并且永远不会卸载,这会导致内存泄漏和性能下降。 最简单的解决方案是使用前面提到的两个构造函数之一。 否则,必须将程序集缓存在Hashtable中,如以下示例所示。