Technology Experience

Contenuti gestiti da Igor Damiani
posts - 949, comments - 2741, trackbacks - 15120

My Links

News

  • Questo blog si propone di raccogliere riflessioni, teoriche e pratiche, su tutto quello che riguarda il world-computing che mi sta attorno: programmazione in .NET, software attuale e futuro, notizie provenienti dal web, tecnologia in generale, open-source.

    L'idea è quella di lasciare una sorta di patrimonio personale, una raccolta di idee che un giorno potrebbe farmi sorridere, al pensiero di dov'ero e cosa stavo facendo.

    10/05/2005,
    Milano

Archives

Post Categories

Generale

Come serializzare seriamente (gioco di parole) con .NET

Premetto che questo è il mio post numero 200....EVVIVA!!!

Nel mio ultimo post ho parlato di un metodo spartano, brutale e poco consigliabile per generare un file XML in cui salvare le impostazioni di una qualsiasi nostra applicazione. Il metodo che ho scritto, sebbene funzioni, ha suscitato qualche reazione negativa, perchè come giustamente è stato osservato non è assolutamente il modo migliore per serializzare su XML. In questo post, dopo averci ragionato su per circa 24 ore, propongo il metodo più politically-correct, quello migliore ed adatto a sfruttare meglio le capacità del framework.
Ovvero, sfruttare i namespace System.Xml e System.Xml.Serialization offerti da .NET.
Vediamo innanzitutto dove sta il problema e come è stato risolto.

Il problema? Color (nel nostro caso) ed altre classi del framework (in tutti gli altri casi)
Supponiamo di avere una classe Settings che debba esporre Name e Style. Name è di tipo string, mentre Style è di tipo Color . La classe è implementata, come solito, da membri privati e membri pubblici. L'ho dotata di due metodi statici:

public static void Serialize(Settings Which);
public static Settings Deserialize(string FileName);

Il primo serializza e genera il file XML. Il secondo legge il file e restituisce un'istanza di Settings.
Detto questo, testiamo un attimo con una manciata di righe C#, così:

Settings mySett = new Settings();
mySett.Name = "Nome";
mySett.Style = Color.Red;
Settings.Serialize(mySett);

Il metodo Serialize non fa altro che:

XmlSerializer ser = new XmlSerializer(typeof(Settings));
StreamWriter wri = 
new StreamWriter(@"D:\Pippo.xml", false, System.Text.Encoding.ASCII);
ser.Serialize(wri, Which);

Il codice è esclusivamente a scopo di test, quindi perdonatemi il D:\Pippo.xml cablato nel codice.  Una volta che il codice ha girato, apro il file XML appena creato, ed ottengo quanto segue:

<?xml version="1.0" encoding="us-ascii"?>
<Settings 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <
Name>Nome</Name>
  <
Style />
<
/Settings>

La property Name della classe è stata serializzata correttamente, mentre Style è vuota. Sto googlando ancora alla ricerca di un motivo: ho trovato milioni e milioni di links, ma siccome non ne ho trovato nessuno che ritengo valido, preferisco andare avanti meglio nella mia ricerca, oppure che magari qualcuno segnali qualche buon link.

Come risolviamo il problema?
La prima cosa che mi è venuta in mente è di usare un'altra classe al posto della classe Color. Con "un'altra classe" intendo una classe scritta da noi, che possa wrappare in qualche modo la classe Color.
Io ho quindi creato una classe HappySignColor. Questa classe espone banalmente 4 membri di tipo int, quindi perfettamente serializzabili nativamente da .NET: i membri sono A (Alpha), R (Red), G (Green) e B (Blue). Ho creato un paio di costruttori utili & veloci ed ho creato un metodo GetColor():

public Color GetColor()
{
    Color ret = Color.FromArgb(_A, _R, _G, _B);
    
return(ret);
}

che non fa altro che ritornare un'istanza di Color costruita con la combinazione ARGB. Questa classe, ripeto, è perfettamente serializzabile. Adesso, basta andare nella classe Settings ed usare HappySignColor al posto di Color ed il gioco è fatto. Proviamo un po'.

Il codice di test finale
Dopo aver opportunamente corretto Settings, usiamo questo codice di test:

Settings mySett = new Settings();
mySett.Name = "Nome";
mySett.Style = 
new HappySignColor(0, 255, 100, 50);
Settings.Serialize(mySett);

La property Style è di tipo HappySignColor, ricordiamocelo. La chiamata a Serialize cosa produce? Produce un file XML di questo tipo:

<?xml version="1.0" encoding="us-ascii"?>
<Settings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>Nome</Name>
  <Style>
    <A>255</A>
    <R>255</R>
    <G>100</G>
    <B>50</B>
  </Style>
</Settings>

La property Style è stata "scomposta" nei suoi 4 membri pubblici ed il gioco è fatto! Il metodo Deserialize funziona al contrario: dato un filename XML, lo apre, lo legge, lo deserializza e ritorna al chiamante un oggetto di tipo Settings.

Ultimo appunto: come utilizzare HappySignColor
Giusto per precisazione. Abbiamo visto come Style sia di tipo HappySignColor. Non posso usarla nativamente come Color: un eventuale istruzione this.BackColor = mySett.Style; genera una bella exception. Per questo motivo ho creato il metodo GetColor(). Io posso scrivere qualcosa tipo this.BackColor = mySett.Style.GetColor(); et voilà. Questa volta il gioco è veramente fatto!!!

Voglio farvi credere che questa soluzione mi piaccia.
Durante la stesura di questo post, è stato commesso del male a .NET Framework.

powered by IMHO 1.2

Print | posted on giovedì 10 novembre 2005 19:11 | Filed Under [ I miei freeware Sviluppo .NET ]

Feedback

Gravatar

# re: Come serializzare seriamente (gioco di parole) con .NET

Io ci metterei pure un cast implicito da HappySignColor a Color, in modo che this.BackColor = mySett.Style funzioni...
10/11/2005 19:47 | Diego Guidi
Gravatar

# Classe Color, serializzazione XML, WebServices...

16/11/2005 19:04 | GisSharpBlog
Gravatar

# Levitra.

Levitra. Unfaithfullness and levitra..
06/01/2010 23:25 | Levitra.
Gravatar

# Hydrocodone apap.

Watson hydrocodone. Hydrocodone. Hydrocodone for sale. Buying hydrocodone without a prescription.
09/01/2010 23:51 | Hydrocodone.
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET