使用.Net使用XmlSerializer有哪些限制(如果有的话)? 例如,您可以将图像序列化为XML吗?
答案 0 :(得分:22)
我通常发现XmlSerializer对于任何不仅仅是DTO的POCO来说都是一个糟糕的选择。如果你需要特定的XML,你可以使用Xml * Attribute和/或IXmlSerializable路由 - 但是你留下了一个非常糟糕的对象。
出于某些目的,它仍然是一个明显的选择 - 即使有它的局限性。但是,为了简单地存储和重新加载数据,我发现BinaryFormatter是一个更容易的选择,而且陷阱更少。
以下是XmlSerializer的一些烦恼列表 - 大部分时间我都被咬过,其他一些我在MSDN找到了:
XmlSerializer为实现IEnumerable或ICollection的类提供特殊处理。实现IEnumerable的类必须实现一个带有单个参数的公共Add方法。 Add方法的参数必须与从GetEnumerator返回的值的Current属性返回的类型相同,或者该类型的base之一。
除了IEnumerable之外,实现ICollection(例如CollectionBase)的类必须具有一个公共Item索引属性(C#中的索引器),该属性采用整数,并且它必须具有integer类型的公共Count属性。 Add方法的参数必须与Item属性返回的类型相同,或者是该类型的基础之一。对于实现ICollection的类,要从序列化的Item属性中检索要序列化的值,而不是通过调用GetEnumerator。
为了提高性能,XML序列化基础结构动态生成程序集以序列化和反序列化指定的类型。基础结构查找并重用这些程序集。仅当使用以下构造函数时才会出现此问题:
XmlSerializer.XmlSerializer(类型) XmlSerializer.XmlSerializer(Type,String)
如果使用任何其他构造函数,则会生成同一程序集的多个版本,并且永远不会卸载,这会导致内存泄漏和性能下降。
如果满足以下条件,则无法实例化XmlSerializer以序列化枚举:枚举的类型为unsigned long(C#中为ulong),枚举包含值大于9,223,372,036,854,775,807的任何成员。
XmlSerializer类不再序列化标记为[已废弃]的对象。
您必须有权写入临时目录(由TEMP环境变量定义)以反序列化对象。
答案 1 :(得分:18)
XmlSerializer有一些缺点。
我(愚蠢地)编写了我自己的序列化程序来解决其中的一些问题。不要那样做;这是一项很多工作,你会在几个月后发现微妙的错误。我在编写自己的序列化器和格式化程序时获得的唯一一点就是对对象图序列化中涉及的细节的更大理解。
我在WCF问世时找到了NetDataContractSerializer。它完成了XmlSerializer不能完成的所有内容。它以与XmlSerializer类似的方式驱动序列化。一个用属性修饰各种属性或字段,以通知序列化程序要序列化的内容。我替换了我用NetDataContractSerializer编写的自定义序列化程序,并对结果非常满意。我强烈推荐它。
答案 2 :(得分:3)
另一个问题是调用XmlSerializer的构造函数将在运行时编译代码并生成一个临时DLL(在%temp%文件夹中),其中包含执行de / serialization的代码。
如果将以下行添加到app.config,则可以查看代码:
<system.diagnostics>
<switches>
<add name="XmlSerialization.Compilation" value="4"/>
</switches>
</system.diagnostics>
第一次序列化类需要花费大量时间,并且需要具有编译和写入磁盘权限的代码。
解决这个问题的方法是使用VS 2005+附带的sGen.exe工具预编译这些DLL。
答案 3 :(得分:2)
不确定是否有任何限制..但是在.NET 1.1中的XmlSerialization中存在内存泄漏错误,你必须创建一个缓存序列化器对象来解决这个问题......事实上,我不确定如果此问题已在.net 2.0或更新版本中修复...
答案 4 :(得分:1)
我能想到的一个限制是XmlSerialization是选择退出;意味着您不希望序列化的类的任何属性必须使用[XmlIgnore]进行修饰。与DataContractSerializer对比,其中所有属性都是选择加入,您必须显式声明包含属性。这是一个很好的write-up。
XmlSerializer将图像或其二进制数组序列化为base64编码文本。
答案 5 :(得分:1)
你写的任何课程理论上都可以通过XmlSerializer提供。然而,它只能访问公共字段,并且需要使用正确的属性(例如XmlAttribute)标记类。即使在基本框架中,并非所有东西都支持XmlSerializer。 System.Collections.Generic.Dictionary&LT;&GT;例如。
答案 6 :(得分:1)
例如,您无法序列化实现IDictionary接口的类。
答案 7 :(得分:0)
对于集合,他们需要使用一个参数的Add方法。如果您只需要文本格式而不是特定的xml,则可以尝试使用JSON。我已经开发了一个用于.NET的JsonExSerializer,还有其他一些用于http://www.json.org。