Condividi tramite


Serializzazione

Nota

Questo contenuto viene ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms and Patterns for Reusable .NET Libraries, 2nd Edition. Tale edizione è stata pubblicata nel 2008 e il libro è stato completamente rivisto nella terza edizione. Alcune informazioni in questa pagina potrebbero non essere aggiornate.

La serializzazione è il processo di conversione di un oggetto in un formato che può essere facilmente persistente o trasportato. Ad esempio, è possibile serializzare un oggetto, trasferirlo su Internet tramite HTTP e deserializzarlo nel computer di destinazione.

In .NET Framework sono disponibili tre tecnologie di serializzazione principali ottimizzate per vari scenari di serializzazione. Nella tabella seguente vengono elencate tali tecnologie e vengono indicati i principali tipi .NET Framework correlati.

Nome tecnologia Tipi principali Scenari
Serializzazione dei contratto dati DataContractAttribute
DataMemberAttribute
DataContractSerializer
NetDataContractSerializer
DataContractJsonSerializer
ISerializable
Persistenza generale
Servizi Web
JSON
Serializzazione XML XmlSerializer Formato XML con controllo completo sulla forma del codice XML
Serializzazione di runtime (binaria e SOAP) SerializableAttribute
ISerializable
BinaryFormatter
SoapFormatter
Servizi remoti .NET

✔️ PRENDERE IN CONSIDERAZIONE la serializzazione quando si progettano nuovi tipi.

Scelta della tecnologia di serializzazione corretta da supportare

✔️ CONSIDERARE il supporto della serializzazione del contratto dati se le istanze del tipo potrebbero dover essere rese persistenti o usate nei servizi Web.

✔️ Considerare il supporto della serializzazione XML al posto di o in aggiunta alla serializzazione del contratto dati se è necessario disporre di maggiore controllo sul formato XML creato quando il tipo viene serializzato.

Questo aspetto può essere necessario in alcuni scenari di interoperabilità in cui è necessario utilizzare un costrutto XML non supportato dalla serializzazione dei contratti dati, ad esempio per creare attributi XML.

✔️ CONSIDERARE il supporto della serializzazione di runtime se le istanze del tipo devono attraversare i limiti di comunicazione remota .NET.

❌ EVITARE di supportare la serializzazione di runtime o la serializzazione XML solo per motivi di persistenza generali. Dare invece la preferenza alla serializzazione dei contratti dati.

Supporto della serializzazione dei contratti dati

Affinché i tipi supportino la serializzazione dei contratti dati, è necessario applicare DataContractAttribute al tipo e DataMemberAttribute ai membri (campi e proprietà) del tipo.

✔️ VALUTARE la possibilità di contrassegnare i membri dati del tipo pubblico se il tipo può essere usato in attendibilità parziale.

In condizioni di attendibilità totale, i serializzatori dei contratti dati possono serializzare e deserializzare anche tipi e membri non pubblici, mentre in condizioni di attendibilità parziale possono essere serializzati o deserializzati solo i membri pubblici.

✔️ IMPLEMENTARE un getter e un setter in tutte le proprietà con DataMemberAttribute. Affinché il tipo possa essere considerato serializzabile, i serializzatori dei contratti dati richiedono entrambi i metodi. In .NET Framework 3.5 SP1 alcune proprietà della raccolta possono essere di sola lettura. Se il tipo non verrà utilizzato in condizioni di attendibilità parziale, è possibile che una o entrambe le funzioni di accesso alle proprietà non siano pubbliche.

✔️ Utilizzare i callback di serializzazione per l'inizializzazione di istanze deserializzate.

Poiché i costruttori non vengono chiamati quando gli oggetti sono deserializzati, Esistono due eccezioni alla regola. I costruttori di raccolte contrassegnati con CollectionDataContractAttribute vengono chiamati durante la deserializzazione. Pertanto, qualsiasi logica eseguita durante la costruzione normale deve essere implementata come uno dei callback di serializzazione.

OnDeserializedAttribute è l'attributo di callback più comunemente utilizzato. Gli altri attributi della famiglia sono OnDeserializingAttribute, OnSerializingAttribute e OnSerializedAttribute. Tali attributi possono essere utilizzati rispettivamente per contrassegnare callback eseguiti prima della deserializzazione, prima della serializzazione e dopo la serializzazione.

✔️ CONSIDERARE l'utilizzo di KnownTypeAttribute per indicare tipi concreti da utilizzare in caso di deserializzazione di un oggetto grafico complesso.

✔️ CONSIDERARE la compatibilità con le versioni precedenti e successive quando si creano o si modificano tipi serializzabili.

Tenere presente che i flussi serializzati di versioni future del tipo possono essere deserializzati nella versione corrente del tipo e viceversa.

È importante comprendere che nelle versioni future del tipo non è possibile modificare il nome, il tipo o l'ordine dei membri dati, anche privati e interni, a meno che non si presti particolare attenzione a mantenere il contratto utilizzando parametri espliciti per gli attributi del contratto dati.

Testare la compatibilità della serializzazione quando si apportano modifiche ai tipi serializzabili. provando ad esempio a deserializzare la nuova versione in una versione precedente e viceversa.

✔️ CONSIDERARE l'implementazione dI IExtensibleDataObject per consentire le sequenze di andata e ritorno tra versioni diverse del tipo.

L'interfaccia consente al serializzatore di verificare che durante le sequenze di andata e ritorno non venga perso alcun dato. La proprietà IExtensibleDataObject.ExtensionData viene utilizzata per archiviare tutti i dati della versione futura del tipo sconosciuto alla versione corrente, e quindi non può archiviarlo nei relativi membri dati. Successivamente, quando la versione corrente viene serializzata e deserializzata in una versione futura, i dati aggiuntivi saranno disponibili nel flusso serializzato.

Supporto della serializzazione XML

La serializzazione dei contratti dati è la tecnologia di serializzazione principale e predefinita in .NET Framework, anche se non supporta tutti gli scenari di serializzazione. ad esempio non consente di controllare completamente la forma del codice XML creato o utilizzato dal serializzatore. Se è richiesto un controllo così dettagliato, è necessario usare la serializzazione XML nonché progettare i tipi in modo che supportino questa tecnologia di serializzazione.

❌ EVITARE di progettare in maniera specifica i tipi per la serializzazione XML, a meno che non sia presente un motivo estremamente valido per controllare la forma del codice XML creato. Questa tecnologia è stata sostituita dalla serializzazione dei contratti dati descritta nella sezione precedente.

✔️ CONSIDERARE l'implementazione dell'interfacciaIXmlSerializable se si desidera maggiore controllo sulla forma del codice XML serializzato rispetto a quello offerto applicando gli attributi della serializzazione XML. Per controllare completamente il flusso XML serializzato, è possibile utilizzare due metodi dell'interfaccia, ovvero ReadXml e WriteXml. È inoltre possibile controllare l'XML Schema generato per il tipo applicando XmlSchemaProviderAttribute.

Supporto della serializzazione di runtime

La serializzazione di runtime è una tecnologia usata dai servizi remoti .NET. Se si ritiene che i tipi verranno trasportati utilizzando i servizi remoti .NET, è necessario verificare che supportino la serializzazione di runtime.

Il supporto di base per la serializzazione di runtim può essere fornito applicando SerializableAttribute, e scenari più avanzati prevedono l'implementazione di un semplice modello di runtime serializzabile (implementazione di ISerializable e specifica di un costruttore di serializzazione).

✔️ CONSIDERARE il supporto della serializzazione di runtime se i tipi verranno utilizzati con i servizi remoti .NET. Lo spazio dei nomi System.AddIn, ad esempio, utilizza i servizi remoti .NET e pertanto tutti i tipi scambiati tra i componenti aggiuntivi System.AddIn devono supportare la serializzazione di runtime.

✔️ Considerare l'implementazione del modello di runtime serializzabile se si vuole il controllo completo sul processo di serializzazione. ad esempio se si desidera trasformare i dati quando vengono serializzati o deserializzati.

Il modello è molto semplice. È sufficiente implementare l'interfaccia ISerializable e specificare un costruttore speciale utilizzato quando l'oggetto viene deserializzato.

✔️ Creare il costruttore di serializzazione in modo protetto e specificare due parametri digitati e denominati esattamente come indicato nell'esempio.

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

✔️ IMPLEMENTARE i membri ISerializable in modo esplicito.

✔️ APPLICARE una richiesta di collegamento all'implementazione ISerializable.GetObjectData. In questo modo si garantisce che solo il core completamente attendibile e il serializzatore di runtime abbiano accesso al membro.

Parti protette da copyright © 2005, 2009 Microsoft Corporation. Tutti i diritti sono riservati.

Ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2a edizione di Krzysztof Cwalina and Brad Abrams, pubblicato il 22 ottobre 2008 da Addison-Wesley Professional nella collana Microsoft Windows Development Series.

Vedi anche