Serializzazione di base

Il modo più semplice per rendere una classe serializzabile è di contrassegnarla con l'attributo Serializable come descritto di seguito.

[Serializable]
public class MyObject {
  public int n1 = 0;
  public int n2 = 0;
  public String str = null;
}

Nell'esempio di codice che segue viene illustrato come un'istanza di questa classe può essere serializzata in un file.

MyObject obj = new MyObject();
obj.n1 = 1;
obj.n2 = 24;
obj.str = "Some String";
IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, obj);
stream.Close();

In questo esempio viene utilizzato un formattatore binario per eseguire la serializzazione. È sufficiente creare un'istanza del flusso e il formattatore che si desidera utilizzare, quindi chiamare il metodo Serialize sul formattatore. Il flusso e l'oggetto da serializzare sono forniti come parametri per la chiamata. Benché nell'esempio non sia esplicitamente dimostrato, tutte le variabili membro di una classe verranno serializzate, comprese quelle contrassegnate come private. Sotto questo aspetto, la serializzazione binaria differisce da quella che si ottiene con la classe XMLSerializer, con cui vengono serializzati solo i campi pubblici. Per informazioni sull'esclusione di variabili membro dalla serializzazione binaria, vedere Serializzazione selettiva.

Il ripristino dell'oggetto allo stato precedente è altrettanto facile. È necessario creare innanzitutto un flusso per la lettura e un formattatore, quindi passare le istruzioni al formattatore perché deserializzi l'oggetto. Nell'esempio di codice che segue vengono illustrate le modalità di esecuzione di questa operazione.

IFormatter formatter = new BinaryFormatter();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
MyObject obj = (MyObject) formatter.Deserialize(stream);
stream.Close();

// Here's the proof.
Console.WriteLine("n1: {0}", obj.n1);
Console.WriteLine("n2: {0}", obj.n2);
Console.WriteLine("str: {0}", obj.str);

Il BinaryFormatter utilizzato sopra è molto efficiente e produce un flusso di byte compatto. Tutti gli oggetti serializzati con questo formattatore possono essere deserializzati con lo stesso formattatore, il che rende questo strumento ideale per serializzare oggetti che verranno deserializzati sulla piattaforma .NET. È importante notare che quando un oggetto viene deserializzato, i costruttori non vengono chiamati. Questo vincolo, imposto sulla deserializzazione per motivi legati alle prestazioni, viola alcuni comuni contratti tra il runtime e il writer dell'oggetto. Gli sviluppatori devono quindi assicurarsi di aver compreso a fondo le implicazioni connesse alla definizione di un oggetto come serializzabile.

Se la portabilità è un requisito necessario, utilizzare SoapFormatter. È sufficiente sostituire il BinaryFormatter contenuto nel codice sopra riportato con SoapFormatter e chiamare Serialize e Deserialize come mostrato in precedenza. Per l'esempio precedente, questo formattatore produce il seguente output.

<SOAP-ENV:Envelope
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
  xmlns:SOAP- ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soap/envelope/"
  SOAP-ENV:encodingStyle=
  "http://schemas.microsoft.com/soap/encoding/clr/1.0"
  "http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:a1="http://schemas.microsoft.com/clr/assem/ToFile">

  <SOAP-ENV:Body>
    <a1:MyObject id="ref-1">
      <n1>1</n1>
      <n2>24</n2>
      <str id="ref-3">Some String</str>
    </a1:MyObject>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

È importante notare che l'attributo Serializable non può essere ereditato. Se una nuova classe viene derivata da MyObject, dovrà essere anch'essa contrassegnata con l'attributo o non potrà essere serializzata. Quando, ad esempio, si tenta di serializzare un'istanza della classe riportata di seguito, viene restituita una SerializationException per indicare che il tipo MyStuff non è contrassegnato come serializzabile.

public class MyStuff : MyObject 
{
  public int n3;
}

L'attributo Serializable è utile ma presenta delle limitazioni, come dimostrato sopra. Per informazioni su quando contrassegnare una classe per la serializzazione, fare riferimento alle linee guida disponibili in Indicazioni per la serializzazione. La serializzazione non può essere aggiunta a una classe già compilata.

Vedere anche

Serializzazione binaria | Accesso a oggetti in altri domini applicazione mediante .NET Remoting | Serializzazione XML e SOAP