<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>.NET Framework 1.0 / 1.1 / 2.0</title>
        <link>http://www.coding4art.com/category/1.aspx</link>
        <description>.NET Framework 1.0 / 1.1 / 2.0</description>
        <language>en-US</language>
        <copyright>Maurizio</copyright>
        <generator>Subtext Version 2.1.2.2</generator>
        <item>
            <title>TextBox ReadOnly in .NET 2.0 e successivi</title>
            <link>http://www.coding4art.com/archive/2008/02/26/textbox-readonly-in-net-2-0-e-successivi.aspx</link>
            <description>&lt;p&gt;Il controllo TextBox di una web application dispone della proprietà ReadOnly che, ovviamente, impedisce l'interazione dell'utente con il controllo quando è impostata a True. &lt;/p&gt;
&lt;p&gt;Ma c'è un particolare importantissimo da considerare: a partire dalla versione 2.0 del .NET Framework il contenuto di un textbox in modalità "ReadOnly" è inviato al server durante un postback della pagina, ma il server ignora questo valore; in altre parole il contenuto del textbox viene perso durante un postback. Questo comportamento mira ad impedire attacchi alla sicurezza, che potrebbero modificare un valore che dovrebbe essere mantenuto inalterato.&lt;/p&gt;
&lt;p&gt;La perdita del valore del textbox può essere inaccettabile in certi contesti applicativi e potrebbe essere necessario applicare il comportamento in essere prima del Framework 2.0. Per far ciò è necessario impostare la proprietà ReadOnly come attributo del controllo, in questo modo:&lt;/p&gt;
&lt;p&gt;TextBox1.Attributes.Add("readonly","readonly")&lt;/p&gt;
&lt;p&gt;e non impostando a True la relativa proprietà.&lt;/p&gt;
&lt;p&gt;Così facendo il valore del textbox (ovvero la sua proprietà Text) viene inviato al server durante il postback ed è altresì disponibile per l'elaborazione.&lt;/p&gt;
&lt;p&gt; UPDATE: questo aggiornamento è, diciamo così, dovuto: il "copyright" di questa scoperta che ha portato via parecchio tempo prima di venirne a capo non è mio ma della mia collega di lavoro &lt;a class="" href="http://ines.zingarelli.biz/" mce_href="http://ines.zingarelli.biz"&gt;Ines&lt;/a&gt;. Io ho solo raccolto il troubleshooting per aiutare altri programmatori come un tempo altri programmatori hanno aiutato me&lt;/p&gt;&lt;img src="http://www.coding4art.com/aggbug/75.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2008/02/26/textbox-readonly-in-net-2-0-e-successivi.aspx</guid>
            <pubDate>Tue, 26 Feb 2008 03:13:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/75.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2008/02/26/textbox-readonly-in-net-2-0-e-successivi.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/75.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/75.aspx</trackback:ping>
        </item>
        <item>
            <title>Eccezioni non gestite in ASP .NET 2.0</title>
            <link>http://www.coding4art.com/archive/2008/01/10/eccezioni-non-gestite-in-asp-.net-2.0.aspx</link>
            <description>Le eccezioni non gestite generate da una applicazione ASP .NET compilata con la versione 2.0 del .NET Framework sono trattate diversamente da quanto avveniva con le applicazioni ASP .NET compilate con la versione 1.0/1.1. Queste ultime semplicemente ignoravano le eccezioni non gestite sollevate all'esterno del contesto corrente, es. un thread diverso da quello principale, mentre le eccezioni sollevate all'interno del contesto erano trattate normalmente come qualsiasi eccezione non gestita. Con il .NET Framework 2.0 questo comportamento è cambiato: le eccezioni non gestite sollevate fuori dal contesto provocano l'immediata interruzione del worker process e conseguentemente dell'applicazione. L'unica traccia è un laconico messaggio nell'event viewer  (System Log) del tipo "DefaultAppPool terminated unexpected", seguito da un ancor più generico messaggio nell'Application Log (Event Source: .NET Runtine 2.0 Error Reporting).&lt;br /&gt;&lt;br /&gt;Ma questo comportamento (il default) è legato ad una precisa policy di gestione delle eccezioni non gestite e può essere modificato in 2 modi:&lt;br /&gt;&lt;br /&gt;-Aggiungendo le seguenti righe nel file Aspnet.config:&lt;br /&gt;        &amp;lt;configuration&amp;gt; &lt;br /&gt;            &amp;lt;runtime&amp;gt;
        &lt;br /&gt;                &amp;lt;legacyUnhandledExceptionPolicy enabled="true" /&amp;gt;&lt;br /&gt;            &amp;lt;/runtime&amp;gt;
&lt;br /&gt;        &amp;lt;/configuration&amp;gt;&lt;br /&gt;&lt;br /&gt;        per fare in modo che le eccezioni non gestite siano trattate come nel .NET Framework 1.0/1.1, ovvero ignorate (scelta non             &lt;br /&gt;        raccomandata da Microsoft)&lt;br /&gt;&lt;br /&gt;-Creando un opportuno httpModule che si registra per l'evento AppDomain.CurrentDomain.Unhandledexception, attraverso il quale loggare i dettagli dell'eccezione  non gestita verificatasi.&lt;br /&gt;&lt;br /&gt;Il tutto è documentato in questo &lt;a href="http://support.microsoft.com/default.aspx?scid=kb%3bEN-US%3b911816"&gt;articolo&lt;/a&gt;, con un esempio di httpModule.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.coding4art.com/aggbug/70.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2008/01/10/eccezioni-non-gestite-in-asp-.net-2.0.aspx</guid>
            <pubDate>Thu, 10 Jan 2008 12:43:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/70.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2008/01/10/eccezioni-non-gestite-in-asp-.net-2.0.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/70.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/70.aspx</trackback:ping>
        </item>
        <item>
            <title>Metriche del codice e SourceMonitor</title>
            <link>http://www.coding4art.com/archive/2008/01/10/metriche-del-codice-e-sourcemonitor.aspx</link>
            <description>Ho provato &lt;a href="http://www.campwoodsw.com/sourcemonitor.html"&gt;SourceMonitor&lt;/a&gt;, un interessante tool freeware per effettuare metriche sul codice sorgente scritto in vari linguaggi di programmazione, tra cui C#, C, C++, VB .NET, Delphi.&lt;br /&gt;&lt;br /&gt;Attraverso una interfaccia di gestione molto semplice acquisisce una serie di informazioni, le metriche appunto, analizzando il codice sorgente di un progetto. Queste informazioni possono essere salvate in diversi momenti e nominate (checkpoints), onde poter mettere a confronto metriche di uno stesso progetto create in momenti diversi.&lt;br /&gt;&lt;br /&gt;Analizzare le metriche del proprio codice aiuta ad evidenziare eventuali colli di bottiglia, ovvero parti dello stesso da sottoporre a code review, e a migliorare quindi la qualità del codice scritto.&lt;br /&gt;&lt;br /&gt;Ecco un elenco delle metriche a mio avviso più importanti:&lt;br /&gt;&lt;br /&gt;-% delle linee di codice commentate rispetto al totale delle linee di codice presenti in un file;&lt;br /&gt;-Numero delle classi, interfacce o strutture definite in un file;&lt;br /&gt;-Numero medio di metodi per classe, interfaccia o struttura;&lt;br /&gt;-Valore di complessità per tutti i metodi, ovvero numero totale dei diversi percorsi di esecuzione che ogni metodo  possiede (maggiore è questo valore, più "complesso" è il metodo). Questo valore si puo' ottenere sia per singolo  metodo, sia come media della complessità di tutti i metodi presenti.&lt;br /&gt;&lt;br /&gt;Come detto, analizzare le metriche del codice può aiutare a scrivere codice di qualità, e quindi ad essere uno sviluppatore migliore.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.coding4art.com/aggbug/68.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2008/01/10/metriche-del-codice-e-sourcemonitor.aspx</guid>
            <pubDate>Thu, 10 Jan 2008 08:21:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/68.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2008/01/10/metriche-del-codice-e-sourcemonitor.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/68.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/68.aspx</trackback:ping>
        </item>
        <item>
            <title>Fix applicate dal .NET Framework 2.0 SP1</title>
            <link>http://www.coding4art.com/archive/2007/12/24/fix-applicate-dal-.net-framework-2.0-sp1.aspx</link>
            <description>&lt;font size="2"&gt;&lt;font face="Times New Roman"&gt;&lt;font face="Verdana"&gt;A questo &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;945757&amp;amp;sd=rss&amp;amp;spid=8291"&gt;link&lt;/a&gt; è disponibile la serie di fix apportate dal Service Pack 1 del .NET Framework 2.0. Per il momento memorizzo il link, ma non appena il tempo me lo permette conto di dargli una lettura.&lt;/font&gt;&lt;br /&gt;&lt;/font&gt;&lt;/font&gt;&lt;img src="http://www.coding4art.com/aggbug/67.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/12/24/fix-applicate-dal-.net-framework-2.0-sp1.aspx</guid>
            <pubDate>Mon, 24 Dec 2007 07:48:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/67.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/12/24/fix-applicate-dal-.net-framework-2.0-sp1.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/67.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/67.aspx</trackback:ping>
        </item>
        <item>
            <title>Implementazione esplicita di membri di interfaccia</title>
            <link>http://www.coding4art.com/archive/2007/10/25/implementazione-esplicita-di-membri-di-interfaccia.aspx</link>
            <description>&lt;p&gt;&lt;font size="2"&gt;L'implementazione esplicita di una interfaccia presenta caratteristiche significative rispetto ad una implementazione per così dire non esplicita. Ad esempio, si consideri l'interfaccia:&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff"&gt;
&lt;p&gt;&lt;font size="2"&gt;public&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt; &lt;font color="#0000ff"&gt;interface&lt;/font&gt; &lt;font color="#2b91af"&gt;IExplicitImplementation  &lt;/font&gt;&lt;/font&gt;
&lt;p&gt;&lt;font size="2"&gt;{ &lt;font color="#0000ff"&gt;string&lt;/font&gt; Method1(&lt;font color="#0000ff"&gt;string&lt;/font&gt; par); }&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;e la seguente classe che la implementa in modo esplicito:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;public&lt;/font&gt; &lt;font color="#0000ff"&gt;class&lt;/font&gt; &lt;font color="#2b91af"&gt;Class1&lt;/font&gt; : &lt;font color="#2b91af"&gt;IExplicitImplementation  &lt;/font&gt;{&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;string&lt;/font&gt; &lt;font color="#2b91af"&gt;IExplicitImplementation&lt;/font&gt;.Method1(&lt;font color="#0000ff"&gt;string&lt;/font&gt; par) {&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#0000ff"&gt;             return&lt;/font&gt; &lt;font color="#a31515"&gt;"Hello world "&lt;/font&gt; + par; &lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Le caratteristiche salienti sono:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;- Il client che consuma la classe Class1 utilizzando una istanza di quest'ultima è impossibilitato a richiamare il metodo Method1 in quanto quest'ultimo NON fa parte dell'interfaccia pubblica della classe (non è visibile con l'intellisense ed il tentativo di richiamare comunque il metodo genera un errore di compilazione).&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;img src="/cs/photos/maurizios_gallery/images/302/original.aspx" /&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Questo codice genera un errore di compilazione:&lt;/font&gt;&lt;/p&gt;&lt;font color="#2b91af"&gt;
&lt;p&gt;&lt;font size="2"&gt;Class1&lt;/font&gt;&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt; cl1 = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#2b91af"&gt;Class1&lt;/font&gt;();&lt;/font&gt;
&lt;p&gt;&lt;font size="2"&gt;cl1.Method1();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;- Il client che consuma la classe Class1 può invocare il metodo Method1 solo attraverso una istanza dell'interfaccia IExplicitImplementation che la classe stessa implementa esplicitamente. Vale a dire:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#2b91af"&gt;IExplicitImplementation&lt;/font&gt; i = &lt;font color="#0000ff"&gt;new&lt;/font&gt; &lt;font color="#2b91af"&gt;Class1&lt;/font&gt;();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;&lt;font color="#2b91af"&gt;Console&lt;/font&gt;.WriteLine( i.Method1(&lt;font color="#a31515"&gt;"Maurizio"&lt;/font&gt;));&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;Quindi un metodo che implementa esplicitamente una interfaccia è, per così dire, privato e pubblico nello stesso tempo. E' privato perchè non compare nell'interfaccia pubblica della classe e non può essere richiamato attraverso una  istanza della classe stessa; è pubblico perchè può comunque essere richiamato utilizzando una istanza dell'interfaccia.&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;- Un metodo che implementa esplicitamente un membro di una interfaccia non può contenere alcun modificatore di accesso, nè i modificatori static, abstract, override e virtual. L'ultima caratteristica determina anche l'impossibilità di effettuare l'override di una implementazione esplicita di un membro di una interfaccia. Questo ostacolo è comunque raggirabile dichiarando un altro metodo virtuale (e quindi ridefinibile) e richiamando quest'ultimo metodo nel codice che implementa esplicitamente un membro di una interfaccia.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://www.coding4art.com/aggbug/64.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/10/25/implementazione-esplicita-di-membri-di-interfaccia.aspx</guid>
            <pubDate>Thu, 25 Oct 2007 04:13:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/64.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/10/25/implementazione-esplicita-di-membri-di-interfaccia.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/64.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/64.aspx</trackback:ping>
        </item>
        <item>
            <title>Come terminare un processo corrotto in .NET</title>
            <link>http://www.coding4art.com/archive/2007/10/25/come-terminare-un-processo-corrotto-in-.net.aspx</link>
            <description>&lt;p&gt;Da .NET 2.0 in poi è possibile terminare un processo corrotto irreparabilmente attraverso il medodo Environment.Failfast(string message), il quale provvede a:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Scrivere una entry nell'Application Event Log con il messaggio specificato&lt;/li&gt;
&lt;li&gt;NON eseguire alcun blocco try-finally ancora in sospeso&lt;/li&gt;
&lt;li&gt;NON esegue alcun finalizer sugli oggetti ancora in memoria&lt;/li&gt;
&lt;li&gt;Esegue un dump dell'applicazione&lt;/li&gt;
&lt;li&gt;Termina il processo&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;I punti 2-3 sono necessari in un contesto simile in quanto la loro esecuzione potrebbe danneggiare risorse usate dall'applicazione stessa. Tuttavia gli oggetti CriticalFinalizerObject (di cui magari parlerò in un post a parte) sono comunque eseguiti prima di terminare il processo.&lt;/p&gt;&lt;img src="http://www.coding4art.com/aggbug/63.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/10/25/come-terminare-un-processo-corrotto-in-.net.aspx</guid>
            <pubDate>Wed, 24 Oct 2007 22:54:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/63.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/10/25/come-terminare-un-processo-corrotto-in-.net.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/63.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/63.aspx</trackback:ping>
        </item>
        <item>
            <title>XML Serializer Generator Tool</title>
            <link>http://www.coding4art.com/archive/2007/08/18/xml-serializer-generator-tool.aspx</link>
            <description>&lt;p&gt;La serializzazione XML in .NET è una operazione onerosa in termini di risorse di sistema a causa della creazione a runtime di un assembly temporaneo contenente funzionalità fortemente tipizzate di "reader" e "writer" del tipo da serializzare, le quali comportano un utilizzo intensivo di &lt;strong&gt;CodeDom&lt;/strong&gt; e &lt;strong&gt;Reflection&lt;/strong&gt;. Osservando con il tool Reflector il codice del costruttore della classe &lt;strong&gt;XmlSerializer &lt;/strong&gt;(comprendente vari overloads) è possibile notare tutto ciò unito all'utilizzo del meccanismo di caching dell'assembly temporaneo creato (sembra però che non tutti gli overloads del costruttore facciano uso della cache con conseguente creazione dell'assembly ad ogni utilizzo). Questo meccanismo è poco performante sia a causa dell'utilizzo delle classi di &lt;strong&gt;CodeDom&lt;/strong&gt; e &lt;strong&gt;Reflection&lt;/strong&gt;, sia per il rischio di creare più assembly temporanei in funzione del numero di classi da serializzare, che resterebbero in memoria fino allo scaricamento del relativo &lt;strong&gt;AppDomain&lt;/strong&gt; o fino a che non termina il processo. Tutto ciò si riflette negativamente soprattutto sulle applicazioni lato server, ed a lungo andare potrebbe provocare eccezioni fatali, es. una &lt;strong&gt;OutOfMemoryException&lt;/strong&gt;. Per ovviare a questo inconveniente il .NET Framework mette a disposizione il tool a riga di comando &lt;strong&gt;SGEN&lt;/strong&gt; (XML Serializer Generator Tool), il quale, lanciato sull'assembly che contiene i tipi da serializzare, genera un nuovo assembly contenente lo stesso codice che verrebbe generato a runtime con la creazione dell'assembly temporaneo. In definitiva è anticipata la creazione dell'assembly, in questo caso non più temporaneo ma definitivo, poichè basta aggiungere un riferimento ad esso, evitando quindi l'overhead della sua creazione a runtime ed eliminando il rischio di crescita incontrollata delle dimensioni dell'&lt;strong&gt;AppDomain.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Tra le opzioni del comando &lt;strong&gt;SGEN:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;-/compiler&lt;/strong&gt; permette di aggiungere qualsiasi opzione da passare al compilatore &lt;strong&gt;C#. &lt;/strong&gt;Utile per firmare con strong name l'assembly da generare. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;-/keep&lt;/strong&gt; permette di eliminare la cancellazione dei files sorgenti dell'assembly generato. In altre parole lascia i files sorgenti a disposizione dello sviluppatore&lt;/p&gt;
&lt;p&gt;-/&lt;strong&gt;proxytypes&lt;/strong&gt; genera il codice di serializzazione solo per i tipi proxy di un XML Web Service&lt;/p&gt;
&lt;p&gt;-/&lt;strong&gt;reference&lt;/strong&gt; permette di specificare eventuali assembly referenziati dalle classi oggetto di serializzazione&lt;/p&gt;
&lt;p&gt;-/&lt;strong&gt;type&lt;/strong&gt; permette di filtrare i tipi da serializzare che si vogliono includere nell'assembly da generare&lt;/p&gt;
&lt;p&gt;Il comando crea un assembly dal nome &amp;lt;proprio assembly&amp;gt;.XlmSerializers.dll che è possibile aggiungere come riferimento alla propria applicazione.&lt;/p&gt;
&lt;p&gt;Naturalmente qualsiasi aggiunta/cancellazione/modifica ai membri pubblici della classe da serializzare necessiterà della ricreazione dell'assembly attraverso il comando SGEN (la serializzazione XML serializza solo i campi pubblici di una classe, a differenza della serializzazione standard, binaria o SOAP,  che invece serializza anche i campi privati).&lt;/p&gt;&lt;img src="http://www.coding4art.com/aggbug/60.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/08/18/xml-serializer-generator-tool.aspx</guid>
            <pubDate>Sat, 18 Aug 2007 07:24:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/60.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/08/18/xml-serializer-generator-tool.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/60.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/60.aspx</trackback:ping>
        </item>
        <item>
            <title>Deserializzazione in .NET 2.0</title>
            <link>http://www.coding4art.com/archive/2007/02/13/deserializzazione-in-.net-2.0.aspx</link>
            <description>&lt;font face="Verdana" size="2" /&gt;
&lt;p&gt;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:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Additional information: È possibile che la versione non corrisponda. Il tipo Person ha 2 membri, di cui 3 deserializzati.&lt;/em&gt;&lt;/p&gt;&lt;font face="Verdana" size="2"&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;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 &lt;em&gt;OptionalField&lt;/em&gt;. Il tal caso il nuovo campo è deserializzato con il valore &lt;em&gt;null&lt;/em&gt; impostato.&lt;/p&gt;&lt;/font&gt;&lt;img src="http://www.coding4art.com/aggbug/52.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/02/13/deserializzazione-in-.net-2.0.aspx</guid>
            <pubDate>Tue, 13 Feb 2007 12:55:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/52.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/02/13/deserializzazione-in-.net-2.0.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/52.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/52.aspx</trackback:ping>
        </item>
        <item>
            <title>Uso di reflection per invocare metodi interni</title>
            <link>http://www.coding4art.com/archive/2007/01/31/uso-di-reflection-per-invocare-metodi-interni.aspx</link>
            <description>&lt;font face="Verdana" size="2" /&gt;
&lt;p&gt;In un &lt;a title="" href="/cs/blogs/maurizio/archive/2006/11/02/51.aspx" target="" name=""&gt;post&lt;/a&gt; precedente ho parlato dell'uso dell'attributo AllowPartiallyTrustedCallers a proposito della sicurezza applicata all'invocazione di metodi pubblici definiti all'interno di un assembly strong-named.  Rimanendo sempre sullo stesso tema, un altro attributo utile a "limitare" i possibili chiamanti di un determinato metodo è StrongNameIdentityPermissionAttribute, usato in questo modo:&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;[&lt;span style="COLOR: teal"&gt;StrongNameIdentityPermissionAttribute&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;SecurityAction&lt;/span&gt;.LinkDemand, &lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;PublicKey = "public key")]&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes" /&gt;&lt;span style="COLOR: blue; LINE-HEIGHT: 150%; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;public&lt;/span&gt;&lt;span style="LINE-HEIGHT: 150%; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; MyMethod(&lt;span style="COLOR: blue"&gt;string &lt;font color="#000000"&gt;parameter&lt;/font&gt;&lt;/span&gt;) {}&lt;/span&gt;&lt;span style="mso-no-proof: yes"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?&gt;&lt;o:p /&gt;&lt;/span&gt;&lt;/p&gt;&lt;font face="Verdana" size="2"&gt;
&lt;p&gt;La presenza di questo attributo permette la chiamata al metodo MyMethod dell'esempio solo al codice contenuto in un assembly firmato con strong name e che presenta la chiave pubblica specificata nell'attributo stesso. Qualsiasi altro codice che tentasse di invocare il metodo in questione provoca una eccezione del tipo SecurityException. Questa forma di sicurezza è la più affidabile a disposizione se vogliamo proteggere ad esempio metodi sensibili dall'invocazione da parte di codice maligno. Se invece il metodo in questione non è invocato dall'esterno dell'assembly, in altre parole non è public, potremmo pensare che basterebbe limitare il suo ambito di visibilità (es.: private, internal in C# oppure friend in VB.NET) per renderlo sicuro da chiamate da parte di codice non affidabile. Putroppo questa convinzione è errata, poichè attraverso l'uso delle tecniche di reflection può essere invocato qualsiasi metodo con qualsiasi ambito di visibilità, quindi anche i metodi marcati come internal o private. Infatti, utilizzando il tool Reflector oppure semplicemente ildasm è possibile leggere la firma di metodi con qualsiasi visibilità (quindi public, private, protected ed internal). Se il metodo MyMethod fosse "internal", conoscendo la sua firma è possibile invocarlo da un altro assembly via reflection in questo modo:&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;object&lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; x = &lt;span style="COLOR: teal"&gt;Activator&lt;/span&gt;.CreateInstanceFrom(&lt;span style="COLOR: maroon"&gt;"MyAssembly.dll"&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;"MyAssembly.MyNamespace"&lt;/span&gt;).Unwrap();&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes" /&gt;&lt;span style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;span style="COLOR: blue; FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;string&lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt; result = x.GetType().InvokeMember(&lt;span style="COLOR: maroon"&gt;"MyMethod"&lt;/span&gt;, &lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;System.Reflection.&lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.InvokeMethod | System.Reflection.&lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Instance | System.Reflection.&lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.NonPublic, &lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'; mso-bidi-font-size: 10.0pt; mso-no-proof: yes"&gt;&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;, x, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[] { &lt;span style="COLOR: maroon"&gt;"string parameter"&lt;/span&gt; }) &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;bypassando quindi la protezione imposta dal livello di visibilità. &lt;/p&gt;
&lt;p&gt;Da notare che richiamare un metodo non pubblico attraverso reflection richiede il permesso ReflectionPermission, impostabile attraverso l'uso dell'attributo ReflectionPermissionAttribute (in modo dichiarativo), oppure in modo programmatico. &lt;/p&gt;
&lt;p&gt;In assenza di questo permesso è possibile invocare via reflection solo i metodi pubblici.&lt;/p&gt;&lt;/font&gt;&lt;img src="http://www.coding4art.com/aggbug/50.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/01/31/uso-di-reflection-per-invocare-metodi-interni.aspx</guid>
            <pubDate>Wed, 31 Jan 2007 12:48:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/50.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/01/31/uso-di-reflection-per-invocare-metodi-interni.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/50.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/50.aspx</trackback:ping>
        </item>
        <item>
            <title>String intern pool</title>
            <link>http://www.coding4art.com/archive/2007/01/24/string-intern-pool.aspx</link>
            <description>&lt;font face="Verdana" size="2" /&gt;
&lt;p&gt;L'Intern pool, di cui non è la &lt;a title="" href="http://www.xplayn.org/articles/848.aspx" target="" name=""&gt;prima volta&lt;/a&gt; che ne parlo, è un hashtable mantenuto internamente dal CLR contenente stringhe generalmente usate per memorizzare valori costanti. In questo hashtable sono memorizzate le costanti stringa a livello di compilazione ed ogni stringa aggiunta esplicitamente attraverso l'utilizzo del metodo string.Intern, il quale aggiunge una stringa nell'intern pool (quindi nell'hashtable) e ne ritorna il riferimento se la stessa non è già presente, in caso contrario  ritorna sempicemente il riferimento ad essa. In questo modo è garantito che se due stringhe (o più) contengono gli stessi valori letterali sarà utilizzato (e quindi sarà presente in memoria) un unico riferimento, con evidente risparmio di risorse. Oltre a questo metodo, il metodo string.IsInterned ritorna il riferimento alla stringa nell'intern pool se presente, null in caso contrario.&lt;/p&gt;
&lt;p&gt;L'intern pool è utile in opportuni scenari, ma ha un grosso svantaggio: poichè ogni stringa memorizzata nel pool è mantenuta all'interno di un hashtable interno del CLR, ne consegue che ogni stringa risulterà sempre raggiungibile dall'applicazione e quindi sopravviverà ad ogni garbage collector (poichè l'hashtable ne mantiene un riferimento). L'hashtable (e le stringhe in esso memorizzate) sarà distrutto e la memoria occupata reclamata solo quando il relativo appDomain (o processo) terminerà.&lt;/p&gt;
&lt;p&gt;Come già detto, tutte le stringhe costanti sono inserite nell'intern pool automaticamente e quindi la memoria occupata non sarà reclamata fino a che il processo termina.  Questo comportamento è dimostrato dal seguente codice:&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;p&gt;string&lt;/p&gt;&lt;/font&gt;&lt;font size="2"&gt; a = &lt;/font&gt;&lt;font color="#a31515" size="2"&gt;"teststring"&lt;/font&gt;&lt;font size="2"&gt;;&lt;/font&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; b = &lt;/font&gt;&lt;font color="#a31515" size="2"&gt;"teststring"&lt;/font&gt;&lt;font size="2"&gt;;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;&lt;p&gt;&lt;font color="#008000" size="2" /&gt;&lt;/p&gt;&lt;font size="2" /&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; x = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt;.IsInterned(a); 
&lt;p /&gt;
&lt;p /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; y = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt;.IsInterned(b);
&lt;p /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;if&lt;/font&gt;&lt;font size="2"&gt; (x != &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;font size="2"&gt;)
&lt;p /&gt;&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;    Console&lt;/font&gt;&lt;font size="2"&gt;.WriteLine(&lt;/font&gt;&lt;font color="#a31515" size="2"&gt;"string a is interned"&lt;/font&gt;&lt;font size="2"&gt;);
&lt;p /&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;if&lt;/font&gt;&lt;font size="2"&gt; (y != &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;font size="2"&gt;)
&lt;p /&gt;&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;    Console&lt;/font&gt;&lt;font size="2"&gt;.WriteLine(&lt;/font&gt;&lt;font color="#a31515" size="2"&gt;"string b is interned"&lt;/font&gt;&lt;font size="2"&gt;);
&lt;p /&gt;
&lt;p /&gt;&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;Console&lt;/font&gt;&lt;font size="2"&gt;.WriteLine(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;object&lt;/font&gt;&lt;font size="2"&gt;.ReferenceEquals(a,b));&lt;/font&gt;
&lt;p&gt;&lt;font size="2"&gt;L'output prodotto è il seguente:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;string a in interned&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;string b is interned&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font size="2"&gt;true&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Se questo comportamento non è quello desiderato è possibile utilizzare l'attributo a livello di assembly CompilationRelaxationsAttribute (namespace System.Runtime.CompilerServices), il quale permette disabilitare l'utilizzo dell'intern pool di stringhe da parte dell'assembly in cui l'attributo è definito, in questo modo:&lt;/p&gt;&lt;font size="2"&gt;
&lt;p&gt;[assembly: &lt;/p&gt;&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;CompilationRelaxations&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#2b91af" size="2"&gt;CompilationRelaxations&lt;/font&gt;&lt;font size="2"&gt;.NoStringInterning)]&lt;/font&gt;
&lt;p&gt;Applicando questo attributo sarebbe lecito aspettarsi che l'intern pool di stringhe non sia più gestito. Invece non è così, nonostante la documentazione MSDN affermi il contrario. Sembra che questo attributo non abbia alcun effetto pratico se non negli assembly precompilati in codice nativo con l'utility NGEN. In altre parole, inserendo o non inserendo l'attributo, l'intern pool è comunque gestito dal CLR, a meno che non si precompili l'assembly con NGEN.&lt;/p&gt;
&lt;p&gt;Come controprova di quanto affermato è possibile eseguire il codice sopraindicato con o senza l'attributo CompilationRelaxations. L'output sarà in ogni caso identico, e dimostrerà che le 2 stringhe sono inserite nell'intern pool.&lt;/p&gt;
&lt;p&gt;Mi piacerebbe conoscere pareri di eventuali altri sviluppatori che hanno già riscontrato questo comportamento.&lt;/p&gt;&lt;img src="http://www.coding4art.com/aggbug/49.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>maurizio</dc:creator>
            <guid>http://www.coding4art.com/archive/2007/01/24/string-intern-pool.aspx</guid>
            <pubDate>Wed, 24 Jan 2007 13:01:00 GMT</pubDate>
            <wfw:comment>http://www.coding4art.com/comments/49.aspx</wfw:comment>
            <comments>http://www.coding4art.com/archive/2007/01/24/string-intern-pool.aspx#feedback</comments>
            <wfw:commentRss>http://www.coding4art.com/comments/commentRss/49.aspx</wfw:commentRss>
            <trackback:ping>http://www.coding4art.com/services/trackbacks/49.aspx</trackback:ping>
        </item>
    </channel>
</rss>