Domanda

Mi sembra di poter serializzare le classi che non hanno quell'interfaccia, quindi non sono chiaro sul suo scopo.

È stato utile?

Soluzione

ISerializable viene utilizzato per fornire una serializzazione binaria personalizzata, in genere per BinaryFormatter (e forse per scopi remoti). Senza di essa, utilizza i campi, che possono essere:

  • inefficiente; se ci sono campi che vengono utilizzati solo per l'efficienza in fase di esecuzione, ma possono essere rimossi per la serializzazione (ad esempio, un dizionario può apparire diverso quando serializzato)
  • inefficiente; come anche per i campi necessari, deve includere molti metadati aggiuntivi
  • non valida; se ci sono campi che non possono essere serializzati (come i delegati di eventi, sebbene possano essere contrassegnati [Non serializzati] )
  • fragile; la serializzazione è ora associata ai nomi field - ma i campi devono essere un dettaglio di implementazione; vedi anche Offuscamento, serializzazione e proprietà implementate automaticamente

Implementando ISerializable puoi fornire il tuo meccanismo di serializzazione binaria. Si noti che l'equivalente xml di questo è IXmlSerializable , utilizzato da XmlSerializer ecc.

Ai fini DTO, BinaryFormatter dovrebbe essere evitato - cose come xml (tramite XmlSerializer o DataContractSerializer ) o json sono buone, così come sono incrociate formati di piattaforma come i buffer di protocollo.

Per completezza, protobuf-net include hook per ISerializable (che consente di utilizzare un formato binario portatile senza scrivere un sacco di codice), ma BinaryFormatter non sarebbe la tua prima scelta qui comunque.

Altri suggerimenti

Le classi possono essere serializzate in .NET in due modi:

  1. Contrassegnare la classe con SerializableAttribute e decorare tutti i campi che non si desidera serializzare con l'attributo Non serializzato . (Come sottolinea Marc Gravell, BinaryFormatter , che è la classe generalmente utilizzata per formattare gli oggetti ISerializable , serializza automaticamente tutti i campi a meno che non siano specificamente contrassegnati diversamente.)
  2. Implementazione dell'interfaccia ISerializable per la serializzazione completamente personalizzata.

Il primo è più semplice da usare in quanto comporta semplicemente la marcatura di dichiarazioni con attributi, ma è limitato nella sua potenza. Quest'ultimo consente una maggiore flessibilità ma richiede uno sforzo significativamente maggiore per l'implementazione. Quale dovresti usare dipende completamente dal contesto.

Riguardo a quest'ultimo ( ISerializable ) e al suo utilizzo, ho citato da pagina MSDN per l'interfaccia:

  

Qualsiasi classe che potrebbe essere serializzata   deve essere contrassegnato con il simbolo   SerializableAttribute. Se una lezione   deve controllare la sua serializzazione   processo, può implementare il   Interfaccia ISerializable. The Formatter   chiama GetObjectData a   tempo di serializzazione e popola il   fornito SerializationInfo con tutto   i dati richiesti per rappresentare il   oggetto. Il formatter crea un   SerializationInfo con il tipo di   oggetto nel grafico. Oggetti che necessitano   per inviare proxy per se stessi possono utilizzare   FullTypeName e AssemblyName   metodi su SerializationInfo da modificare   le informazioni trasmesse.

     

In caso di eredità di classe, esso   è possibile serializzare una classe che   deriva da una classe base che   implementa ISerializable. In questo   caso, la classe derivata dovrebbe chiamare   l'implementazione della classe base di   GetObjectData al suo interno   implementazione di GetObjectData.   Altrimenti, i dati dalla base   la classe non verrà serializzata.

Con ISerializable puoi scrivere metodi personalizzati nel tuo oggetto per assumere la serializzazione durante la serializzazione binaria, per serializzare i tuoi oggetti in un modo diverso da quello che farà l'approccio predefinito usato da BinaryFormatter.

In altre parole, se l'approccio predefinito serializza l'oggetto in modo diverso rispetto a come si desidera serializzare, è possibile implementare ISerializable per un controllo completo. Nota che, insieme a ISerializable, c'è anche un costruttore personalizzato che dovresti implementare.

XmlSerialization utilizzerà ovviamente solo proprietà, ISerializable non ha nulla a che fare con la serializzazione XML.

Grazie a Marc e Pop per i commenti, ero un po 'frettoloso con la mia prima risposta.

Per rendere un oggetto "trasportabile", è necessario serializzarlo. Ad esempio, se si desidera trasferire i dati degli oggetti utilizzando .NET Remoting o i servizi Web, è necessario fornire metodi che serializzano i dati degli oggetti, riducendo le istanze degli oggetti in un formato trasportabile che rappresenta una rappresentazione ad alta fedeltà dell'oggetto.

Quindi puoi anche prendere la rappresentazione serializzata, trasportarla in un altro contesto come una macchina diversa e ricostruire il tuo oggetto originale.

Quando si implementa l'interfaccia ISerializable , una classe deve fornire il metodo GetObjectData incluso nell'interfaccia, nonché un costruttore specializzato specializzato ad accettare due parametri: un'istanza di SerializationInfo e un'istanza di StreamingContext.

Se le tue classi non richiedono un controllo approfondito del loro stato dell'oggetto, puoi semplicemente usare l'attributo [Serializable] . Le classi che richiedono un maggiore controllo sul processo di serializzazione possono implementare l'interfaccia ISerializable.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top