Compartilhar via


Serialização

Observação

Este conteúdo é reimpresso com permissão da Pearson Education, Inc. de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition. Essa edição foi publicada em 2008 e, desde então, o livro foi totalmente revisado na terceira edição. Algumas das informações nesta página podem estar desatualizadas.

A serialização é o processo de conversão de um objeto em um formato que possa ser prontamente persistido ou transportado. Por exemplo, você pode serializar um objeto, transportá-lo pela Internet usando HTTP e desserializá-lo no computador de destino.

O .NET Framework oferece três tecnologias de serialização principais otimizadas para vários cenários de serialização. A tabela a seguir lista essas tecnologias e os principais tipos de estrutura relacionados a elas.

Nome da Tecnologia Tipos principais Cenários
Serialização do contrato de dados DataContractAttribute
DataMemberAttribute
DataContractSerializer
NetDataContractSerializer
DataContractJsonSerializer
ISerializable
Persistência geral
Serviços Web
JSON
Serialização XML XmlSerializer Formato XML com controle total sobre a forma do XML
Serialização de runtime (binário e SOAP) SerializableAttribute
ISerializable
BinaryFormatter
SoapFormatter
Comunicação remota .NET

✔️ PENSE sobre a serialização ao criar tipos.

Escolhendo a tecnologia de serialização correta que receberá suporte

✔️ CONSIDERE dar suporte à Serialização de Contrato de Dados se houver possibilidade de que as instâncias do seu tipo precisem ser persistentes ou usadas nos Serviços Web.

✔️ CONSIDERE dar suporte à serialização XML em vez ou além da Serialização do Contrato de Dados se você precisar ter mais controle sobre o formato XML gerado quando o tipo for serializado.

Isso talvez seja necessário em alguns cenários de interoperabilidade no qual você precise usar um constructo XML para o qual não haja suporte na Serialização do Contrato de Dados, por exemplo, para gerar atributos XML.

✔️ CONSIDERE dar suporte à Serialização em Runtime se as instâncias do tipo precisarem ultrapassar os limites da comunicação remota .NET.

❌ EVITE dar suporte à Serialização em Runtime ou à serialização XML apenas por motivos gerais de persistência. Prefira a Serialização do Contrato de Dados em vez disso.

Oferecendo suporte à serialização do contrato de dados

Os tipos podem dar suporte à Serialização do Contrato de Dados aplicando o DataContractAttribute ao tipo e o DataMemberAttribute aos membros (campos e propriedades) do tipo.

✔️ CONSIDERE marcar os membros de dados do tipo público se o tipo puder ser usado na confiança parcial.

Na confiança total, os serializadores do Contrato de Dados podem serializar e desserializar tipos e membros não públicos, mas somente os membros públicos podem ser serializados e desserializados na confiança parcial.

✔️ IMPLEMENTE um getter e um setter em todas as propriedades que têm DataMemberAttribute. Os serializadores do Contrato de Dados exigem o getter e o setter para o tipo sejam considerados serializáveis. (No .NET Framework 3.5 SP1, algumas propriedades de coleção podem ser somente get.) Se o tipo não for usado em confiança parcial, um ou ambos os acessadores de propriedade poderão ser não públicos.

✔️ CONSIDERE usar retornos de chamada de serialização para a inicialização de instâncias desserializadas.

Os construtores não são chamados quando os objetos são desserializados. (Há exceções à regra. Construtores de coleções marcadas com CollectionDataContractAttribute são chamados durante a desserialização.) Portanto, qualquer lógica executada durante a construção normal precisa ser implementada como um dos retornos de chamada de serialização.

OnDeserializedAttribute é o atributo de retorno de chamada mais usado. Os outros atributos da família são OnDeserializingAttribute, OnSerializingAttribute e OnSerializedAttribute. Eles podem ser usados para marcar os retornos de chamada que são executados antes de desserialização, antes da serialização e, por fim, após a serialização, respectivamente.

✔️ CONSIDERE usar o KnownTypeAttribute para indicar os tipos concretos que devem ser usados ao desserializar um grafo de objetos complexos.

Considere a compatibilidade com versões anteriores e posteriores ao criar ou modificar tipos serializáveis.

Tenha em mente que os fluxos serializados de versões futuras do tipo podem ser desserializados na versão atual de tipo e vice-versa.

Verifique se compreendeu que os membros de dados, até mesmo os privados e internos, não podem alterar seus nomes, tipos ou mesmo sua ordem nas versões futuras do tipo, a menos que se tome um cuidado especial para preservar o contrato usando parâmetros explícitos para os atributos do contrato de dados.

Teste a compatibilidade da serialização ao fazer alterações a tipos serializáveis. Tente desserializar a nova versão em uma versão antiga e vice-versa.

✔️ CONSIDERE implementar IExtensibleDataObject para permitir o ciclo completo entre diferentes versões do tipo.

A interface permite que o serializador assegure de que nenhum dado sejam perdido durante o ciclo completo. A propriedade IExtensibleDataObject.ExtensionData é usada para armazenar dados da versão futura do tipo que é desconhecido para a versão atual e, portanto, não pode armazená-los em seus membros de dados. Quando a versão atual for serializada e desserializada subsequentemente em uma versão futura, os dados adicionais estarão disponíveis no fluxo serializado.

Suporte à serialização XML

A Serialização do Contrato de Dados é a tecnologia de serialização principal (padrão) do .NET Framework, mas há situações de serialização para as quais a Serialização do Contrato de Dados não oferece suporte. Por exemplo, ela não fornece controle total sobre o formato XML gerado ou consumido pelo serializador. Se esse controle fino for necessário, a Serialização XML precisará ser usada e você precisará criar seus tipos para oferecer suporte essa tecnologia de serialização.

❌ EVITE criar os tipos especificamente para a Serialização XML, a menos que você tenha um motivo muito forte para controlar a forma do XML gerado. Essa tecnologia de serialização foi substituída pela serialização do contrato de dados abordada na seção anterior.

✔️ CONSIDERE implementar a interface IXmlSerializable se quiser ainda mais controle sobre a forma do XML serializado do que o que é oferecido aplicando os atributos de Serialização XML. Dois métodos da interface, ReadXml e WriteXml, permitem que você controle totalmente o fluxo XML serializável. Você também pode controlar o esquema XML gerado para o tipo aplicando XmlSchemaProviderAttribute.

Suporte à serialização em runtime

A seSialização em Runtime é uma tecnologia usada pelo .NET Remoting. Se você considerar que os tipos serão transportados por meio da comunicação remota .NET, será necessário verificar se eles oferecem suporte à Serialização em Runtime.

O suporte básico da Serialização em Runtime pode ser fornecido aplicando SerializableAttribute, e os cenários mais avançados envolvem a implementação de um Padrão Serializável em Runtime simples (implemente ISerializable e forneça um construtor de serialização).

✔️ CONSIDERE o suporte à Serialização em Runtime se os tipos forem usados com a comunicação remota .NET. Por exemplo, o namespace System.AddIn usa a comunicação remota .NET e, portanto, todos os tipos trocados entre os suplementos System.AddIn precisam oferecer suporte à Serialização em Runtime.

✔️ CONSIDERE implementar o Padrão Serializável em Runtime se quiser controle completo sobre o processo de serialização. Por exemplo, se você quiser transformar os dados à medida que eles forem serializados ou desserializados.

O padrão é muito simples. Tudo o que você precisa fazer é implementar a interface ISerializable e fornecer um construtor especial que é usado quando o objeto é desserializado.

✔️ PROTEJA o construtor de serialização e forneça dois parâmetros tipados e nomeados exatamente conforme mostrado no exemplo aqui.

[Serializable]
public class Person : ISerializable
{
    protected Person(SerializationInfo info, StreamingContext context)
    {
        // ...
    }
}

✔️ IMPLEMENTE os membros ISerializable explicitamente.

✔️ APLIQUE uma demanda de link para a implementação de ISerializable.GetObjectData. Isso garantirá que o somente núcleo totalmente confiável e o Serializador em Runtime tenham acesso ao membro.

Portions © 2005, 2009 Microsoft Corporation. Todos os direitos reservados.

Reimpresso com permissão da Pearson Education, Inc. das Diretrizes de Design do Framework: convenções, linguagens e padrões para bibliotecas do .NET reutilizável, 2ª edição por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 por Addison-Wesley Professional como parte da série de desenvolvimento do Microsoft Windows.

Confira também