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.