Partilhar via


Serialização

Observação

Este conteúdo é reimpresso com permissão da Pearson Education, Inc., a partir 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 revisto 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 pode ser prontamente persistido ou transportado. Por exemplo, você pode serializar um objeto, transportá-lo pela Internet usando HTTP e desserializá-lo na máquina de destino.

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

Nome da tecnologia Principais Tipos Cenários
Serialização de contrato de dados DataContractAttribute
DataMemberAttribute
DataContractSerializer
NetDataContractSerializer
DataContractJsonSerializer
ISerializable
Persistência geral
Serviços Web
JSON (JavaScript Object Notation)
Serialização XML XmlSerializer Formato XML com controlo total sobre a forma do XML
Serialização em tempo de execução (binário e SOAP) SerializableAttribute
ISerializable
BinaryFormatter
SoapFormatter
Comunicação remota .NET

✔️ PENSE na serialização ao projetar novos tipos.

Escolhendo a tecnologia de serialização certa para oferecer suporte

✔️ CONSIDERE o suporte à serialização de contrato de dados se instâncias do seu tipo precisarem ser persistentes ou usadas em serviços da Web.

✔️ CONSIDERE oferecer suporte à serialização XML em vez da serialização de contrato de dados ou além dela, se necessitar de mais controle sobre o formato XML que é produzido quando o tipo é serializado.

Isso pode ser necessário em alguns cenários de interoperabilidade em que você precisa usar uma construção XML que não é suportada pela serialização de contrato de dados, por exemplo, para produzir atributos XML.

✔️ CONSIDERE dar suporte à serialização de tempo de execução se instâncias do seu tipo precisarem atravessar os limites da comunicação remota do .NET.

❌ EVITE suportar Runtime Serialization ou XML Serialization apenas por motivos gerais de persistência. Em vez disso, prefira a serialização do contrato de dados.

Suporte à serialização de contrato de dados

Os tipos podem oferecer suporte à serialização de contrato de dados aplicando o DataContractAttribute ao tipo e o DataMemberAttribute aos membros (campos e propriedades) do tipo.

✔️ CONSIDERE marcar os campos de dados do seu tipo como públicos se o tipo puder ser usado em confiança limitada.

No contexto de confiança plena, os serializadores de Contrato de Dados podem serializar e desserializar tipos e membros não públicos, mas em confiança parcial, somente membros públicos podem ser serializados e desserializados.

✔️ DO implemente métodos de acesso e modificação em todas as propriedades que têm DataMemberAttribute. Os serializadores de contrato de dados exigem o getter e o setter para que o tipo seja considerado serializável. (No .NET Framework 3.5 SP1, algumas propriedades de coleção podem ser de somente leitura.) Se o tipo não for usado em confiança parcial, um ou ambos os métodos de acesso à propriedade podem ser privados.

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

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

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

✔️ CONSIDERE usar o KnownTypeAttribute para indicar tipos concretos que devem ser usados ao desserializar um gráfico de objeto complexo.

✔️ É importante que considere a compatibilidade com versões anteriores e posteriores ao criar ou alterar tipos serializáveis.

Lembre-se de que fluxos serializados de versões futuras do seu tipo podem ser desserializados para a versão atual do tipo e vice-versa.

Certifique-se de entender que os membros de dados, mesmo privados e internos, não podem alterar seus nomes, tipos ou até mesmo sua ordem em versões futuras do tipo, a menos que seja tomado 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 em tipos serializáveis. Tente desserializar a nova versão para uma versão antiga e vice-versa.

✔️ CONSIDERE a implementação IExtensibleDataObject para permitir a viagem de ida e volta entre diferentes versões do tipo.

A interface permite ao serializador assegurar que nenhum dado seja perdido durante a transferência de dados bidirecional. A IExtensibleDataObject.ExtensionData propriedade é usada para armazenar quaisquer dados da versão futura do tipo que são desconhecidos pela versão atual e, portanto, não podem ser armazenados nos seus membros de dados. Quando a versão atual é subsequentemente serializada e desserializada em uma versão futura, os dados adicionais estarão disponíveis no fluxo serializado.

Suporte à serialização XML

A Serialização de Contrato de Dados é a principal tecnologia de serialização (padrão) no .NET Framework, mas há cenários de serialização que a Serialização de Contrato de Dados não suporta. Por exemplo, ele não lhe dá controle total sobre a forma de XML produzido ou consumido pelo serializador. Se esse controle fino for necessário, a serialização XML deverá ser usada, e você precisará projetar seus tipos para dar suporte a essa tecnologia de serialização.

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

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

Suportando a serialização em tempo de execução

Runtime Serialization é uma tecnologia usada pelo .NET Remoting. Se você acha que seus tipos serão transportados usando a comunicação remota do .NET, você precisa ter certeza de que eles suportam a serialização em tempo de execução.

O suporte básico para Runtime Serialization pode ser fornecido aplicando o SerializableAttribute, e cenários mais avançados envolvem a implementação de um simples padrão de serialização em tempo de execução (implementar ISerializable e fornecer o construtor de serialização).

✔️ CONSIDERE o suporte à serialização em tempo de execução se seus tipos forem usados com a comunicação remota do .NET. Por exemplo, o namespace System.AddIn utiliza a comunicação remota .NET e, portanto, todos os tipos trocados entre suplementos System.AddIn precisam oferecer suporte à Serialização de Tempo de Execução.

✔️ CONSIDERE implementar o Runtime Serializable Pattern se quiser ter controle total sobre o processo de serialização. Por exemplo, se você quiser transformar dados à medida que eles são serializados ou desserializados.

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

✔️ DO torna o construtor de serialização protegido e fornece dois parâmetros digitados e nomeados exatamente como mostrado no exemplo aqui.

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

✔️ IMPLEMENTE os ISerializable membros explicitamente.

✔️ NÃO aplique uma demanda de link à ISerializable.GetObjectData implementação. Isso garante que apenas o núcleo totalmente confiável e o Runtime Serializer tenham acesso ao membro.

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

Reimpresso com permissão da Pearson Education, Inc., a partir de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition por Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 pela Addison-Wesley Professional como parte da Microsoft Windows Development Series.

Ver também