【问题标题】:What are all these null collection entries in my DataContract XML?我的 DataContract XML 中的所有这些空集合条目是什么?
【发布时间】:2011-01-30 21:47:06
【问题描述】:

有人知道为什么 NetDataContractSerializer 可能会在序列化集合中添加“nil”条目吗?

例如,

  <Jobs z:Id="17">
    <_items z:Id="18" z:Size="4">
      <JobRecord z:Id="19">
        <Name z:Id="20">Job1</Name>
      </JobRecord>
      <JobRecord i:nil="true" />
      <JobRecord i:nil="true" />
      <JobRecord i:nil="true" />
    </_items>
    <_size>1</_size>
    <_version>2</_version>
  </Jobs>

请注意三个额外的“JobRecord”条目和附加元素“嘿,我知道这里有四个节点,但其中只有一个意味着什么。”

这似乎是一种奇怪的行为。好的,所以我可以看到 NDCS 深入到对象图中,并且可能正在使用一个大小大于被序列化的项目数的支持数组(想想一个列表的支持数组)。

这是怎么回事?它是构造函数创建的用于处理yield return(这是 JobRecord 的来源)的类的工件吗?

【问题讨论】:

  • 你能显示序列化它的代码吗?您提到“收益回报”,但不清楚这与此 XML 有何关系。

标签: .net xml null netdatacontractserializer xml-nil


【解决方案1】:

在 .net 中,集合和列表在空间不足时通过自动调整大小来工作。为了提高效率,他们不只是在每次用完时将大小调整为 1,而是使用内部算法来调整大小并留出一些额外空间,目的是他们不必经常调整大小。

您在这里看到的是正在序列化的集合,所有额外的空间也被序列化。这是因为序列化将集合完全按原样存储,所以当你反序列化它时,你会得到相同的结果,并留下相同数量的内部空间。

如果您使用的是列表,则可以通过查看Capacity 属性来检查内部保留空间。

如果您想在序列化集合之前删除任何多余的空间,您可以调用。

myStuff.Capacity = myStuff.Count;

这会将可用容量设置为与包含的项目数相同,因此不会有保留空间。

很遗憾,如果它是您使用的集合,容量不可用,您只需要信任该集合即可在内部调整大小。

无论哪种方式,除非您需要非常节省空间,否则我不会太担心它。如果这样做,请改用固定大小的数组。

【讨论】:

  • 我正在使用编译器放入实现yield return 的类中的任何内容。我不认为它会包含我的返回类型的数组。这似乎仍然是一种非常奇怪的行为。我认为序列化器会触发枚举器,获取结果并将其粘贴到适当大小的数组或堆栈中,然后将其发送到线路中。
  • @Will。你能发布你用来序列化的代码吗?我对您使用 yield 的方式很感兴趣。
  • 我认为真正的答案是 NDCS 在序列化时会在幕后偷看,因此它实际上会触及集合的内部并对其进行序列化。
【解决方案2】:

只是猜测,但请注意z:Size="4"。对我来说看起来像四个 JobRecord 条目,我猜其中三个 = null

【讨论】:

  • 哇!这正是我在问题中所说的!你的阅读理解不错!现在,为什么 NDCS 这样做???
  • @Will:当您谈到附加元素时,没有意识到您指的是属性。当然,它这样做是为了让您可以反序列化您序列化的内容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 2012-11-14
  • 2021-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多