Newsgroup: it.comp.dotnet
Titolo: Problema con serializzazione e binary formatter

Ciao a tutti.
Avendo la necessità di serializzare una gerarchia di classi 
discretamente grande che descrive un modello di dati, ho pensato di 
provare a usare il binary formatter del .net e decorare le classi 
interessate con l'attributo [Serializable] e imponendo il 
[NonSerialized] o [field: NonSerialized] dove non mi serviva la 
persistenza (impostazione, come dicono "loro", "opt-out").
Purtroppo la classe "padre" Application ha due membri siffatti:
         public event ScopeEventHandler scopeAdded;
         public event ScopeEventHandler scopeRemoved;
e c'è un ViewModel chiamato VariableEditorViewModel che sottoscrive tali 
eventi, che però io non voglio serializzare:
             currentApplication.scopeAdded += new 
ScopeEventHandler(currentApplication_scopeAdded);
             currentApplication.scopeRemoved += new 
ScopeEventHandler(currentApplication_scopeRemoved);
uno di questi due gestori è così fatto:
         private void currentApplication_scopeAdded(object sender, 
ScopeEventArgs e)
         {
             _treeViewItemsVMCollection.Add(new ScopeViewModel(e.Scope));
             this.OnPropertyChanged("TreeViewItemsVMCollection");
         }
dove _treeViewItemsVMCollection è una collection bindata all'itemssource 
di una treeview. In pratica lo scopo di tutto ciò è assicurare che 
quando al modello viene aggiunto un elemento (scope) la view soprastante 
se ne accorga ed aggiunga un nodo all'albero presente nella UI, passando 
attraverso il viewmodel "mediatore".
Vedendo che la richiesta di serializzare VariableEditorViewModel 
derivava proprio dalla sottoscrizione degli eventi della classe di 
modello, pensavo che per evitare ciò bastasse imporre:
[field: NonSerialized]
public event ScopeEventHandler scopeAdded;
e infatti non mi viene più richiesto di rendere VariableEditorViewModel 
[Serializable], ma con mia somma sorpresa (dovuta probabilmente a somma 
ignoranza) mi viene richiesta la serializzabilità di...
ScopeViewModel !!!
di cui viene invocata l'istanziazione nel gestore 
currentApplication_scopeAdded di cui sopra.
Come è possibile? "che cavolo sta succedendo, Willis?"
Come esco dall'impasse?
Grazie

 public event ScopeEventHandler scopeAdded;
fai la prova di esplicitare l'evento in field + accessor usando 
add/remove. Quindi metti NonSerialized sulla dichiarazione del field.
-- 
Raffaele Rialdi  
http://www.iamraf.net
Weblog: 
http://blogs.ugidotnet.org/raffaele
Microsoft MVP profile 
https://mvp.support.microsoft.com/profile/raffaele
UGIdotNET - 
http://www.ugidotnet.org/


         //VERSIONE ESTESA
         [NonSerialized]
         private ScopeEventHandler _scopeAdded;
         public event ScopeEventHandler scopeAdded
         {
             add { _scopeAdded += value; } // Not Thread-safe
             remove { _scopeAdded -= value; } // Not Thread-safe
         }
così, giusto? già provato, non va neanché così.
Per ora ho abdicato, ripiegando sul DataContractSerializer che con i 
dovuti cambiamenti e settaggi ora funziona e non si tira dietro il 
viewmodel. Poi forse per i miei scopi va pure meglio.
Comunque grazie per la risposta!


Prego. Hai sicuramente da qualche parte un altro reference 
(probabilmente indiretto) che punta al VM.
Il DataContractSerializer ha il vantaggio di essere opt-in e quindi 
serializza solo ciò che marchi esplicitamente con datamember, ma è 
molto 'povero'.
Hai provato invece il NetDataContractSerializer? È decisamente più 
performante.


 performante.
Ho visto che esiste, ma non conoscendolo ritenevo che fosse usato solo 
per scopi più "remoti". Magari gli do uno sguardo, grazie ancora.

 scopi più "remoti". Magari gli do uno sguardo, grazie ancora.
In pratica il Net usa le info di assembly e type del clr, evitando così 
la verbosità necessaria a descriverli in xml. Questo riduce l'xml e di 
conseguenza migliora le performance.
