Quais são todas essas entradas de coleta nula no meu Datacontract XML?
-
21-09-2019 - |
Pergunta
Alguém sabe por que o NetDatacontractSerializer pode adicionar entradas "nil" em uma coleção serializada?
Por exemplo,
<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>
Observe as três entradas extras "JobRecord" e o elemento adicional dizendo "Ei, eu sei que existem quatro nós aqui, mas apenas um deles significa qualquer coisa".
Parece um comportamento estranho. Ok, então eu pude ver que o NDCS espia profundamente no gráfico de objetos e pode estar girando com uma matriz de apoio que tem um tamanho maior que o número de itens que estão sendo serializados (pense na matriz de apoio para uma lista).
É isso que está acontecendo aqui? É um artefato da classe que o construtor cria para lidar yield return
(Qual é a fonte do JobRecord)?
Solução
As coleções e listas do .NET funcionam por redimensionamento automático quando ficarem sem espaço. Para tornar isso eficiente, eles não redimensionam 1 a mais cada vez que acabam, eles usam um algoritmo interno para redimensionar e deixar algum espaço extra, o objetivo é que eles não precisem redimensionar com muita frequência.
O que você está vendo aqui é a coleção sendo serializada com todo o espaço extra sendo serializado também. Isso ocorre porque a serialização está armazenando a coleção exatamente como ela é, então, quando você a desaperializa, obtém o mesmo de volta, com o mesmo número de espaço interno restante.
Se for uma lista que você está usando, você pode verificar o espaço reservado internamente, olhando para o Capacity
propriedade.
Se você deseja remover algum espaço extra antes de serializar a coleção que você pode ligar.
myStuff.Capacity = myStuff.Count;
Isso definirá a capacidade disponível como o mesmo que o número de itens contidos; portanto, não haverá espaço reservado.
Infelizmente, se for uma coleção que você está usando a capacidade não está disponível, você só precisa confiar na coleção para redimensionar internamente.
De qualquer forma, eu não me preocuparia muito com isso, a menos que você precise ser realmente muito eficiente em termos de espaço. Se o fizer, use uma matriz de tamanho fixo.
Outras dicas
Apenas um palpite, mas observe o z:Size="4"
. Parece quatro JobRecord
entradas para mim, e acho que três deles = null
.