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 voler 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 salvarlo in un file. Quindi potresti serializzare immagini, file di dati, lo stato corrente di un modulo di programma ('state' è come un'istantanea del tuo programma in un dato momento in modo da poter temporaneamente sospendere l'esecuzione e ricominciare più tardi) ... qualunque cosa tu debba fare.

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

Ecco perché la serializzazione è un processo chiave in .NET e Visual Basic. Di seguito è una sezione sulla serializzazione personalizzata implementando il ISerializable interfaccia e codifica a Nuovo e a GetObjectData sottoprogramma.

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

Modulo SerializeParms
ParmExample di classe pubblica
   Public Parm1Name As String = "Nome Parm1"
   Public Parm1Value As Integer = 12345
   Parm2Name pubblico come stringa
   Parm2 pubblico Valore come decimale
End Class
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 pubblica 1
   Private Sub mySerialize_Click (_
      Mittente ByVal come System.Object, _
      ByVal e As System.EventArgs) _
      Gestisce mySerialize.Click
      Dim ParmData come nuovo ParmExample
      ParmData.Parm2Name = "Nome Parm2"
      ParmData.Parm2Value = 54321.12345
      Dim s come nuovo FileStream ("ParmInfo", FileMode.Create)
      Dim f come nuovo BinaryFormatter
      f.Serialize (s, ParmData)
      s.Close ()
   End Sub
End Class

E quegli stessi valori possono essere recuperati in questo modo:

Importa System.Runtime.Serialization.Formatters.Binary
Importa System.IO
Modulo di classe pubblica 1
   Sottotitoli privati ​​myDeserialize_Click (_
      Mittente ByVal come System.Object, _
      ByVal e As System.EventArgs) _
      Gestisce myDeserialize.Click
      Dim s = New FileStream ("ParmInfo", FileMode.Open)
      Dim f come nuovo BinaryFormatter
      Dim RestoredParms come nuovo esempio Parm
      RestoredParms = f.Deserialize (s)
      s.Close ()
      Console.WriteLine (RestoredParms.Parm1Name)
      Console.WriteLine (RestoredParms.Parm1Value)
      Console.WriteLine (RestoredParms.Parm2Name)
      Console.WriteLine (RestoredParms.Parm2Value)
   End Sub
End Class

UN Struttura o una raccolta (come un Lista di array) anziché a Classe potrebbe anche essere serializzato su un file allo stesso modo.

Ora che abbiamo esaminato il processo di serializzazione di base, diamo un'occhiata ai dettagli specifici che fanno parte del processo nella pagina successiva.

Una delle prime cose che dovresti notare in questo esempio è il attributo in Classe. Gli attributi sono solo più informazioni che puoi fornire a VB.NET su un oggetto e sono usati per molte cose diverse. L'attributo in questo codice dice a VB.NET di aggiungere altro codice in modo che in seguito tutto ciò che può essere incluso in questa classe possa essere serializzato.

Se ci sono elementi specifici nella classe che si non fare vuoi essere serializzato, puoi usare il attributo per escluderli:

Public Parm3Value As String = "Qualunque cosa"

Nell'esempio, si noti che Serialize e Deserialize sono metodi del BinaryFormatter oggetto (f in questo esempio).

f.Serialize (s, ParmData)

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

E un'ultima nota, se il tuo oggetto include altri oggetti subordinati, anche questi saranno serializzati! Ma da allora tutti oggetti serializzati dovere essere contrassegnato con il simbolo 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 nel Blocco note per vedere come appaiono i dati serializzati. (Se hai seguito questo codice, dovrebbe essere nel 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 eventuali stringhe nel tuo file serializzato. Successivamente faremo una versione XML e potresti voler confrontare i due solo per essere consapevoli della differenza.

La serializzazione in XML anziché in un file binario richiede pochissime modifiche. XML non è così veloce e non è in grado di acquisire alcune informazioni sugli oggetti, ma è molto più flessibile. XML può essere utilizzato praticamente da qualsiasi altra tecnologia software al mondo oggi. Se vuoi essere sicuro che le tue strutture di 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 ultima tecnologia, ma molte persone preferiscono ancora questo metodo.

La "X" in XML sta per eXtensible. Nel nostro esempio XML, useremo una di quelle estensioni di XML, una tecnologia chiamata SAPONE. 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 tasto 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 lo fa riferimento.

Importa System.Runtime.Serialization.Formatters.Soap
Dim f As New SoapFormatter

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

Nome Parm1
12345
Nome Parm2
54.321,12,345 mila

C'è anche un sacco di XML aggiuntivo lì che è necessario anche per lo standard SOAP nel file. Se si desidera verificare quale l'attributo fa, puoi aggiungere una variabile con quell'attributo e guardare il file per verificare che non sia incluso.

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

A tale scopo, è necessario approfondire 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, comporta un costo di codifica aggiuntiva.

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

Importa System.Runtime.Serialization
_
CustomSerialization di classe pubblica
   Implementa ISerializable
   'dati da serializzare qui
   'Pubblico serializzato Variabile come tipo
   Public Sub Nuovo ()
   'costruttore predefinito quando la classe
   "è stato creato - può essere un codice personalizzato
   'aggiunto anche qui
   End Sub
   Public Sub 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 del programma
   End Sub
End Class

L'idea è che ora puoi (e, in effetti, tu dovere) esegue tutto l'aggiornamento e la lettura dei dati nell'archivio dati serializzato in Nuovo e GetObjectData subroutine. È inoltre necessario includere un generico Nuovo costruttore (nessun elenco di parametri) perché stai implementando un'interfaccia.

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

'Proprietà generica
NewPropertyValue As String privato
Proprietà pubblica NewProperty () As String
   Ottenere
      Restituisce newPropertyValue
   End Get
   Set (valore ByVal come stringa)
      newPropertyValue = value
   Set finale
Proprietà finale
"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 Nuovo la subroutine sarà simile a questa:

Public Sub 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")
   'Nuovi sottotitoli continuano ...

quando Deserialize viene chiamato a BinaryFormatter oggetto, questo sub viene eseguito e a SerializationInfo l'oggetto viene passato a Nuovo sottoprogramma. New può quindi fare tutto il necessario con i valori dei dati serializzati. Per esempio…

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

Il contrario accade quando Serialize si chiama, ma il BinaryFormatter chiamate oggetto GetObjectData anziché.

Public Sub GetObjectData (_
   ByVal info As SerializationInfo, _
   ByVal context As StreamingContext) _
   Implementa ISerializable.GetObjectData
   'aggiorna l'archivio dati serializzato
   "dalle variabili del programma
   Se Parm2Name = "Test" Quindi
      info.AddValue ("a", "Questo è un test.")
   Altro
      info.AddValue ("a", "Nessun test questa volta.")
   Finisci se
   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 vero codice funzionante. Ci si chiede se l'autore abbia effettivamente eseguito qualsiasi codice prima di scrivere l'articolo a volte.