Tutto sulla serializzazione in Visual Basic

La serializzazione è il processo di conversione di un oggetto in una sequenza lineare di byte chiamata "flusso di byte". La deserializzazione inverte semplicemente il processo. Ma perché dovresti convertire un oggetto in un flusso di byte?

Il motivo principale è che puoi spostare l'oggetto. Considera le possibilità. Poiché "tutto è un oggetto" in .NET, puoi serializzare qualsiasi cosa e salvarla in un file. Quindi puoi serializzare immagini, file di dati, lo stato corrente di un modulo di programma ('stato' è come un'istantanea del tuo programma in un punto nel tempo in modo da poter sospendere temporaneamente l'esecuzione e ricominciare più tardi) ... fare.

È inoltre possibile archiviare questi oggetti su disco in file, inviarli sul Web, passarli a un programma diverso, conservare una copia di backup per sicurezza o protezione. Le possibilità sono letteralmente infinite.

Ecco perché la serializzazione è un processo così fondamentale in .NET e Visual Basic. Di seguito è riportata una sezione sulla serializzazione personalizzata implementando il ISerializzabile interfaccia e codifica a Novitá e GetObjectData sottoprogramma.

Come primo esempio di serializzazione, facciamo uno dei programmi più semplici, ma anche uno dei più utili: serializzare i dati, quindi deserializzare i dati in una semplice classe da e verso un file. In questo esempio, i dati non vengono solo serializzati, ma viene salvata anche la struttura dei dati. La struttura qui è dichiarata in un modulo per mantenere le cose ... ben ... strutturate.

Modulo SerializeParms
Classe pubblica ParmExample
   Public Parm1Name As String = "Parm1 Name"
   Public Parm1Value As Integer = 12345
   Public Parm2Name As String
   Public Parm2Value As Decimal
Classe finale
Modulo finale

Quindi, i singoli valori possono essere salvati in un file come questo:

Importa System.Runtime.Serialization.Formatters.Binary
Importa System.IO
Modulo di classe pubblica1
   Sottotitoli privati ​​mySerialize_Click (_
      ByVal mittente As System.Object, _
      ByVal e As System.EventArgs) _
      Gestisce mySerialize.Click
      Dim ParmData As New ParmExample
      ParmData.Parm2Name = "Nome Parm2"
      ParmData.Parm2Value = 54321.12345
      Dim s As New FileStream ("ParmInfo", FileMode.Create)
      Dim f come nuovo BinaryFormatter
      f.Serialize (s, ParmData)
      s.Chiudi ()
   End Sub
Classe finale

E quegli stessi valori possono essere recuperati in questo modo:

Importa System.Runtime.Serialization.Formatters.Binary
Importa System.IO
Modulo di classe pubblica1
   Sottotitoli privati ​​myDeserialize_Click (_
      ByVal mittente As System.Object, _
      ByVal e As System.EventArgs) _
      Gestisce myDeserialize.Click
      Dim s = New FileStream ("ParmInfo", FileMode.Open)
      Dim f come nuovo BinaryFormatter
      Dim RestoredParms As New ParmEsempio
      RestoredParms = f.Deserialize (s)
      s.Chiudi ()
      Console.WriteLine (RestoredParms.Parm1Name)
      Console.WriteLine (RestoredParms.Parm1Value)
      Console.WriteLine (RestoredParms.Parm2Name)
      Console.WriteLine (RestoredParms.Parm2Value)
   End Sub
Classe finale

A Structure o una raccolta (come un file Lista di array) piuttosto che a Classe potrebbe anche essere serializzato in un file in questo modo.

Ora che abbiamo esaminato il processo di serializzazione di base, esaminiamo i dettagli specifici che fanno parte del processo nella pagina successiva.

Una delle prime cose che dovresti notare di questo esempio è il file attributo in Classe. Gli attributi sono solo ulteriori informazioni che puoi fornire a VB.NET su un oggetto e vengono utilizzati per molte cose diverse. L'attributo in questo codice dice a VB.NET di aggiungere codice extra in modo che in seguito, tutto in questa classe possa essere serializzato.

Se nella classe sono presenti elementi specifici che non si desidera serializzare, è possibile utilizzare il file attributo per escluderli:

Public Parm3Value As String = "Qualunque cosa"

Nell'esempio, l'avviso è quello serializzare e Deserializza sono metodi di BinaryFormatter oggetto (f in questo esempio).

f.Serialize (s, ParmData)

Questo oggetto prende l'estensione FileStream oggetto e l'oggetto da serializzare come parametri. Vedremo che VB.NET offre un altro oggetto che permette di esprimere il risultato come XML.

E un'ultima nota, se il tuo oggetto include altri oggetti subordinati, verranno serializzati anche loro! Ma poiché tutti gli oggetti serializzati devono essere contrassegnati con l'estensione attributo, anche tutti questi oggetti figlio devono essere contrassegnati in questo modo.

Solo per essere completamente chiari su ciò che sta accadendo nel tuo programma, potresti voler visualizzare il file denominato ParmData in Blocco note per vedere l'aspetto dei dati serializzati. (Se hai seguito questo codice, dovrebbe essere nel file bin.Debug cartella nel progetto.) Poiché si tratta di un file binario, la maggior parte del contenuto non è testo leggibile, ma dovresti essere in grado di vedere tutte le stringhe nel file serializzato. Successivamente faremo una versione XML e potresti voler confrontare i due solo per essere consapevole della differenza.

La serializzazione in XML invece che in un file binario richiede pochissime modifiche. XML non è così veloce e non può acquisire alcune informazioni sugli oggetti, ma è molto più flessibile. XML può essere utilizzato da quasi tutte le altre tecnologie software nel mondo oggi. Se vuoi essere sicuro che le strutture dei tuoi file non ti "leghino" a Microsoft, questa è una buona opzione da esaminare. Microsoft sta enfatizzando "LINQ to XML" per creare file di dati XML nella loro tecnologia più recente, ma molte persone preferiscono ancora questo metodo.

La "X" in XML sta per eXtensibile. Nel nostro esempio XML, useremo una di quelle estensioni di XML, una tecnologia chiamata SOAP. Questo significava "Simple Object Access Protocol", ma ora è solo un nome. (SOAP è stato aggiornato così tanto che il nome originale non si adatta più così bene.)

La cosa principale che dobbiamo cambiare nelle nostre subroutine è la declazione del formattatore di serializzazione. Questo deve essere modificato sia nella subroutine che serializza l'oggetto che in quella che lo deserializza nuovamente. Per la configurazione predefinita, ciò comporta tre modifiche al programma. Innanzitutto, devi aggiungere un riferimento al progetto. Fare clic con il pulsante destro del mouse sul progetto e selezionare Aggiungi riferimento .... Assicurarsi ...

System.Runtime.Serialization.Formatters.Soap

... è stato aggiunto al progetto.

Quindi modificare le due istruzioni nel programma che fa riferimento a esso.

Importa System.Runtime.Serialization.Formatters.Soap

Dim f come nuovo SoapFormatter

Questa volta, se controlli lo stesso ParmData file in Blocco note, vedrai che il tutto è in un testo XML leggibile come ...

Nome parm1
1
Nome parm2
2

C'è anche molto XML aggiuntivo necessario per lo standard SOAP nel file. Se vuoi verificare quale sia il file attributo, puoi aggiungere una variabile con quell'attributo e guardare il file per verificare che non sia incluso.

L'esempio che abbiamo appena codificato ha solo serializzato i dati, ma supponiamo che sia necessario controllare il modo in cui i dati vengono serializzati. Anche VB.NET può farlo!

Per ottenere ciò, è necessario approfondire un po 'il concetto di serializzazione. VB.NET ha un nuovo oggetto per aiutare qui: SerializationInfo. Sebbene tu abbia la possibilità di codificare il comportamento di serializzazione personalizzato, viene fornito con un costo di codifica aggiuntiva.

Il codice extra di base è mostrato di seguito. Ricorda, questa classe viene utilizzata al posto di ParmExample classe mostrata nell'esempio precedente. Questo non è un esempio completo. Lo scopo è mostrarti il ​​nuovo codice necessario per la serializzazione personalizzata.

Importa System.Runtime.Serialization
_
CustomSerialization della classe pubblica
   Implementa ISerializable
   'dati da serializzare qui
   'Public SerializedVariable come tipo
   Sottotitoli pubblici Nuovo ()
   'costruttore predefinito quando la classe
   'viene creato - il codice personalizzato può essere
   'aggiunto anche qui
   End Sub
   Sottotitoli pubblici Nuovo (_
      ByVal info As SerializationInfo, _
      ByVal context As StreamingContext)
      'inizializza le variabili del tuo programma da
      'un archivio dati serializzato
   End Sub
   Public Sub GetObjectData (_
      ByVal info As SerializationInfo, _
      ByVal context As StreamingContext) _
      Implementa ISerializable.GetObjectData
      'aggiorna l'archivio dati serializzato
      'dalle variabili di programma
   End Sub
Classe finale

L'idea è che ora puoi (e, in effetti, devi) fare tutto l'aggiornamento e la lettura dei dati nell'archivio dati serializzato nel Novitá e GetObjectData subroutine. Devi includere anche un generico Novitá costruttore (nessun elenco di parametri) perché stai implementando un'interfaccia.

La classe normalmente avrà anche proprietà formali e metodi codificati ...

'Proprietà generica
NewPropertyValue As String privato
Proprietà pubblica NewProperty () As String
   Ottieni
      Restituisce newPropertyValue
   Fine Ottieni
   Set (ByVal value As String)
      newPropertyValue = valore
   Fine serie
Fine proprietà

'Metodo generico
Public Sub MyMethod ()
   'codice metodo
End Sub

La classe serializzata risultante può creare valori univoci nel file in base al codice fornito. Ad esempio, una classe immobiliare potrebbe aggiornare il valore e l'indirizzo di una casa, ma la classe serializzerebbe anche una classificazione di mercato calcolata.

Il progetto Novitá la subroutine sarà simile a questa:

Sottotitoli pubblici Nuovo (_
   ByVal info As SerializationInfo, _
   ByVal context As StreamingContext)
   'inizializza le variabili del tuo programma da
   'un archivio dati serializzato
   Parm1Name = info.GetString ("a")
   Parm1Value = info.GetInt32 ("b")
   'Il nuovo sottomarino continua ...

quando Deserializza è chiamato a BinaryFormatter oggetto, questo sub viene eseguito e un file SerializationInfo oggetto viene passato al file Novitá sottoprogramma. New può quindi fare tutto ciò che è necessario con i valori dei dati serializzati. Per esempio ...

MsgBox ("Questo è Parm1Value Times Pi:" _
   & (Parm1Value * Math.PI) .ToString)

Il contrario accade quando serializzare si chiama, ma il BinaryFormatter chiamate di oggetti GetObjectData anziché.

Public Sub GetObjectData (_
   ByVal info As SerializationInfo, _
   ByVal context As StreamingContext) _
   Implementa ISerializable.GetObjectData
   'aggiorna l'archivio dati serializzato
   'dalle variabili di programma
   If Parm2Name = "Test" Allora
      info.AddValue ("a", "Questo è un test.")
   Altro
      info.AddValue ("a", "Nessun test questa volta.")
   End If
   info.AddValue ("b", 2)

Si noti che i dati vengono aggiunti al file serializzato come coppie nome / valore.

Molte delle pagine web che ho trovato scrivendo questo articolo non sembrano avere un codice funzionante. Ci si chiede se l'autore abbia effettivamente eseguito qualche codice prima di scrivere l'articolo a volte.