Что это за записи в моем DataContract XML? - PullRequest
1 голос
/ 23 марта 2010

Кто-нибудь знает, почему NetDataContractSerializer может добавлять «ноль» записей в сериализованную коллекцию?

Например,

  <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 глубоко вглядывается в граф объектов и может вертеться с резервным массивом, размер которого больше, чем количество сериализуемых элементов (вспомним массив поддержки для List).

Это то, что здесь происходит? Это артефакт класса, который конструктор создает для обработки yield return (который является источником JobRecord)?

Ответы [ 2 ]

1 голос
/ 23 марта 2010

В коллекциях и списках .net работает автоматическое изменение размера, когда им не хватает места. Чтобы сделать это эффективным, они не просто меняют размер на 1 каждый раз, когда заканчиваются, они используют внутренний алгоритм для изменения размера и оставляют некоторое дополнительное пространство, цель состоит в том, чтобы им не приходилось слишком часто изменять размер.

То, что вы видите здесь, - это то, что коллекция сериализуется, причем все дополнительное пространство тоже сериализуется. это происходит потому, что сериализация хранит коллекцию в точности так, как она есть, поэтому, когда вы десериализируете ее, вы получите то же самое обратно с тем же количеством оставшегося внутреннего пространства.

Если вы используете Список, вы можете проверить внутренне зарезервированное пространство, посмотрев на свойство Capacity.

Если вы хотите удалить лишние пробелы перед сериализацией коллекции, которую вы можете вызвать.

myStuff.Capacity = myStuff.Count;

Это установит доступную емкость равной количеству содержащихся элементов, поэтому не будет зарезервированного пространства.

К сожалению, если вы используете коллекцию, Capacity недоступен, вам просто нужно довериться коллекции, чтобы сделать ее внутреннее изменение.

В любом случае, я бы не стал слишком беспокоиться об этом, если бы вам не нужно было по-настоящему эффективно использовать пространство. Если вы это сделаете, используйте вместо этого массив фиксированного размера.

0 голосов
/ 23 марта 2010

Просто предположение, но обратите внимание на z:Size="4". Похоже, четыре JobRecord записи для меня, и я думаю, три из них = null.

...