反序列化为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")); 

我错过了什么吗?

未使用添加到SiteXmlRoot属性,因为您没有反序列化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中,如以下示例所示。