Il meccanismo di deserializzazione ha subito una modifica (a mio avviso migliorativa) in .NET 2.0 rispetto a quanto avveniva in .NET 1.1. La versione 2.0 ha la capacità di deserializzare un oggetto anche se questo presenta nella sua forma serializzata informazioni aggiuntive (es. membri pubblici) non presenti invece nella particolare versione dell’oggetto che stiamo deserializzando. Mi spiego meglio. Supponiamo che abbiamo la nostra onnipresente classe Person con 3 campi pubblici, ovvero FirstName, LastName e Age, e che alcune istanze di questa classe siano serializzate in formato binario attraverso l’uso della classe BinaryFormatter utilizzando una applicazione scritta in .NET 2.0, e che il risultato della serializzazione sia memorizzato nel file BinaryPerson.dat. Un’altra applicazione, questa volta scritta in .NET 1.1, deserializza gli oggetti Person contenuti nel file binario, utilizzando però una vecchia versione dell’oggetto Person contenente solo 2 campi pubblici e non 3 (es. FirstName e LastName). In tale scenario il Framework 1.1 quando esegue il metodo Deserialize solleva una eccezione e precisamente:
An unhandled exception of type ‘System.Runtime.Serialization.SerializationException’ occurred in mscorlib.dll
Additional information: È possibile che la versione non corrisponda. Il tipo Person ha 2 membri, di cui 3 deserializzati.
In pratica in .NET 1.1 non è possibile deserializzare un oggetto (Person, nell’esempio) se lo stesso è serializzato con un numero eccedente di membri. Questo comportamento è cambiato in .NET 2.0, in quanto tutti i membri eccedenti riscontrati sono ignorati e nessuna eccezione viene sollevata.
Per completezza, nel caso di uno scenario esattamente opposto a quello descritto, cioè l’applicazione A serializza l’oggetto Person con 3 campi e l’applicazione B cerca di deserializzarlo mentre nel frattempo all’oggetto Person è stato aggiunto il quarto campo, si avrà sempre una eccezione a prescindere dalla versione del Framework utilizzata, tranne se il campo appena aggiunto viene decorato con l’attributo OptionalField. Il tal caso il nuovo campo è deserializzato con il valore null impostato.