Usando .Net Quais as limitações (se houver) estão lá em usar o XmlSerializer?

StackOverflow https://stackoverflow.com/questions/109318

  •  01-07-2019
  •  | 
  •  

Pergunta

Usando .Net Quais as limitações (se houver) estão lá em usar o XmlSerializer? Por exemplo, você pode serializar Imagens para XML?

Foi útil?

Solução

O XmlSerializer tem alguns inconvenientes.

  1. Deve conhecer todos os tipos sendo serializado. Você não pode passar algo por interface que representa um tipo que o serializador não sabe.
  2. Não pode fazer referências circulares.
  3. Será serializa o mesmo objeto várias vezes se referenciada várias vezes no gráfico de objeto.
  4. Não é possível lidar com a serialização campo privado.

I (estupidamente) escrevi o meu próprio serializador para contornar alguns desses problemas. Não faça isso; é um monte de trabalho e você vai encontrar erros sutis em TI meses abaixo da estrada. A única coisa que eu ganhei em escrever meu próprio serializador e formatador foi uma apreciação maior da minúcia envolvido na serialização objeto gráfico.

Eu encontrei o NetDataContractSerializer quando WCF saiu. Ele faz todas as coisas de cima que XmlSerializer não faz. Dirige a serialização de uma forma semelhante ao XmlSerializer. Um decora várias propriedades ou campos com atributos para informar o serializer o que serialize. Eu substituí o serializador personalizado que eu tinha escrito com o NetDataContractSerializer e estava muito feliz com os resultados. Eu recomendo-lo.

Outras dicas

Eu geralmente encontrar o XmlSerializer para ser uma má escolha para qualquer POCO que é mais do que apenas um DTO. Se você precisar de XML específico, você pode ir o XML * Atributo e / ou rota IXmlSerializable -. Mas você é deixado com um objeto muito mutilado

Para alguns propósitos, é ainda uma escolha óbvia - mesmo com suas limitações. Mas, para simplesmente armazenar e recarregar os dados, eu encontrei BinaryFormatter ser uma escolha muito mais fácil com menos armadilhas.

Aqui está uma lista de alguns aborrecimentos com XmlSerializer - a maioria eu fui mordido por em um ponto ou outro, outros eu achei lá no MSDN :

  • Requer um público, há argumentos construtor
  • Apenas serializa público de leitura / gravação propriedades e campos
  • Requer todos os tipos a ser conhecido
  • Na verdade põe em get_ * e * set_, de modo a validação, etc. será executado. Isso pode ser bom ou ruim (pensar sobre a ordem das chamadas também)
  • Só vai serializar coleções IEnumerable ou ICollection em conformidade com regras específicas

O XmlSerializer dá tratamento especial para as classes que implementam IEnumerable ou ICollection. Uma classe que implementa IEnumerable deve implementar um método Add público que usa um único parâmetro. O parâmetro Add do método deve ser do mesmo tipo que é retornado da propriedade atual sobre o valor retornado de GetEnumerator, ou uma das bases desse tipo.

Uma classe que implementa ICollection (como CollectionBase), além de IEnumerable deve ter uma propriedade indexada item público (indexador em C #) que leva um inteiro, e ele deve ter uma propriedade Count pública do tipo inteiro. O parâmetro para o método Add deve ser do mesmo tipo que é retornado da propriedade Item, ou uma das bases desse tipo. Para as classes que implementam ICollection, valores a serem serializados são recuperados a partir da propriedade item indexado, não chamando GetEnumerator.

  • não serialize IDictionary
  • Usa montagens geradas dinamicamente, que não podem ficar descarregadas a partir do domínio do aplicativo.

Para aumentar o desempenho, a infra-estrutura de serialização XML gera dinamicamente montagens para serializar e desserializar tipos especificado. Os achados de infra-estrutura e reutiliza essas assembléias. Este comportamento ocorre apenas quando utilizar os seguintes construtores:

XmlSerializer.XmlSerializer (Type) XmlSerializer.XmlSerializer (Type, String)

Se você usar qualquer um dos outros construtores, várias versões do mesmo assembly são gerados e nunca descarregado, o que resulta em um vazamento de memória e baixo desempenho.

  • Não é possível serializar ArrayList [] ou List []
  • Tem outros casos extremos estranho

O XmlSerializer não pode ser instanciada serializar uma enumeração se as condições que se seguem:. A enumeração é de tipo sem sinal longa (ULONG em C #) e a enumeração contém qualquer membro com um valor maior do que 9.223.372.036.854.775.807

A classe XmlSerializer não serializa objetos que são marcados como [Obsoleto].

Você deve ter permissão para gravar no diretório temporário (como definido pela variável de ambiente TEMP) para desserializar um objeto.

  • requer a leitura .InnerException para obter qualquer informação útil sobre erros

Outro problema é que chamando o construtor do XmlSerializer irá compilar o código em tempo de execução e irá gerar uma DLL temporário (na pasta% temp%) com o código para fazer o de / serialização.

Você pode assistir o código se você adicionar as seguintes linhas ao app.config:

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

Isso leva um monte de tempo a primeira vez que você serializar uma classe e precisa de código com permissões para a compilação e gravação no disco.

Uma maneira de contornar isso é pré-compilar estes DLL utilizando a ferramenta Sgen.exe que vem com o VS 2005 +.

Olhe aqui para mais informações .

Não tenho certeza se há alguma limitação .. Mas havia um bug vazamento de memória no XmlSerialization em .NET 1.1, você meio que teve que criar um objeto de cache serializer de se locomover com esta questão ... Na verdade, eu não estou certo se este problema foi corrigido no .NET 2.0 ou mais recente ...

Qualquer classe que você escreve pode, teoricamente, ser alimentado através de XmlSerializer. Howerver, ele só tem acesso aos campos públicos e as classes precisam ser marcados com os atributos corretos (por exemplo XmlAttribute). Mesmo na estrutura básica, nem tudo suporta XmlSerializer. System.Collections.Generic.Dictionary <>, por exemplo.

A única limitação que eu posso pensar é que XmlSerialization é opt-out; significa quaisquer propriedades de uma classe que você não quer serializado deve ser decorado com [XmlIgnore]. Contraste isso com DataContractSerializer onde todas as propriedades são opt-in, você deve declarar explicitamente atributos de inclusão. Aqui está uma boa write-up.

As imagens ou suas matrizes binárias são serializados como base64 texto codificado por XmlSerializer.

Por exemplo, você não pode aulas serialize implementação de interface de IDictionary.

Para coleções que eles precisam ter um método Add tomando um único argumento. Se você só precisa de um formato de texto e não especificamente XML que você pode tentar JSON. Eu desenvolvi um para .NET, JsonExSerializer , e há outros disponíveis também em http://www.json.org .

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top