使用 .Net 使用 XmlSerializer 有哪些限制(如果有)?

使用 .Net,使用 XmlSerializer 有哪些限制(如果有)? 例如,您可以将图像序列化为 XML 吗?

请先 登录 后评论
本文连接: http://www.china-sunrider.com.cn/question/11189
source: https://stackoverflow.com/questions/109318

8 个回答

RWendi

不确定是否有任何限制..但是.NET 1.1中的XmlSerialization存在内存泄漏错误,您必须创建一个缓存序列化器对象来解决这个问题...事实上,我不确定如果此问题已在 .net 2.0 或更高版本中修复...

请先 登录 后评论
Kris

我能想到的一个限制是 XmlSerialization 是可选择退出的;这意味着您不想序列化的类的任何属性都必须用 [XmlIgnore] 修饰。与所有属性都是可选的 DataContractSerializer 相比,您必须显式声明包含属性。这是一个很好的 写下来

图像或其二进制数组由 XmlSerializer 序列化为 base64 编码文本。

请先 登录 后评论
Scott Pedersen

理论上,您编写的任何类都可以通过 XmlSerializer 提供。但是,它只能访问公共字段,并且类需要使用正确的属性(例如 XmlAttribute)进行标记。即使在基本框架中,也不是所有东西都支持 XmlSerializer。 System.Collections.Generic.Dictionary

请先 登录 后评论
Jason Jackson

XmlSerializer 有一些缺点。

  1. 它必须知道所有正在序列化的类型。您不能通过接口向其传递代表序列化程序不知道的类型的内容。
  2. 它不能进行循环引用。
  3. 如果在对象图中多次引用同一对象,它将多次序列化同一对象。
  4. 无法处理私有字段序列化。

我(愚蠢地)编写了自己的序列化器来解决其中一些问题。不要那样做;这是一项繁重的工作,几个月后您会发现其中存在细微的错误。在编写自己的序列化程序和格式化程序时,我唯一获得的收获是对对象图序列化中涉及的细节有了更多的了解。

我在 WCF 时找到了 NetDataContractSerializer出来。它执行上面 XmlSerializer 不执行的所有操作。它以与 XmlSerializer 类似的方式驱动序列化。人们用属性来装饰各种属性或字段,以通知序列化器要序列化什么。我用 NetDataContractSerializer 替换了我编写的自定义序列化器,并对结果非常满意。我强烈推荐它。

请先 登录 后评论
starec

例如,您无法序列化实现 IDictionary 接口的类。

请先 登录 后评论
Ted Elliott

对于集合,它们需要有一个带有单个参数的 Add 方法。如果您只需要文本格式而不是特定的 xml,您可以尝试 JSON。我为 .NET 开发了一个 JsonExSerializer,并且还有其他可用的 http://www.json.org

请先 登录 后评论
Mark Brackett

我通常发现 XmlSerializer 对于任何不仅仅是 DTO 的 POCO 来说都是一个糟糕的选择。如果您需要特定的 XML,您可以使用 Xml*Attribute 和/或 IXmlSerialized 路线 - 但您会留下一个非常混乱的对象。

出于某些目的,它仍然是一个显而易见的选择 - 即使有其局限性。但是,对于简单地存储和重新加载数据,我发现 BinaryFormatter 是一个更容易的选择,而且陷阱更少。

这里列出了 XmlSerializer 的一些烦恼 - 大多数是我在某个时刻被咬过的,其他的是我在 MSDN

  • 需要一个公共的、无参数的构造函数
  • 仅序列化公共读/写属性和字段
  • 要求了解所有类型
  • 实际上调用了 get_* 和 set_*,因此将运行验证等。这可能是好是坏(也要考虑调用的顺序)
  • 只会序列化符合特定规则的 IEnumerable 或 ICollection 集合

XmlSerializer 对实现 IEnumerable 或 ICollection 的类给予特殊处理。实现 IEnumerable 的类必须实现采用单个参数的公共 Add 方法。 Add 方法的参数必须与从 GetEnumerator 返回的值的 Current 属性返回的类型相同,或者该类型的基之一。

除了 IEnumerable 之外,还实现 ICollection(例如 CollectionBase)的类必须具有公共 Item 索引属性(C 中的索引器)

请先 登录 后评论
Tomer Pintel

另一个问题是,调用 XmlSerializer 的构造函数将在运行时编译代码,并生成一个临时 DLL(在 %temp% 文件夹中),其中包含执行反/序列化的代码。

如果将以下行添加到 app.config 中,您可以观看代码:

  <system.diagnostics>
    <switches>
      <add name="XmlSerialization.Compilation" value="4"/>
    </switches>
  </system.diagnostics>

第一次序列化类时,这会花费大量时间,并且需要具有编译和写入磁盘权限的代码。

解决这个问题的方法是使用 VS 2005 附带的 sGen.exe 工具预编译这些 DLL。

查看此处了解更多信息

请先 登录 后评论
user contributions licensed under CC BY-SA.