<?xml version="1.0" encoding="Windows-1252"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Code and fun - Il blog di Matteo Casati</title><link>http://blogs.aspitalia.com/matteo/</link><description>Code and fun - Il blog di Matteo Casati</description><language>it-it</language><managingEditor>noreply(at)aspitalia.com(Code and fun - Il blog di Matteo Casati)</managingEditor><webMaster>daniele(at)aspitalia.com(Daniele Bochicchio)</webMaster><copyright>1998-2008 ASPItalia.com/Code and fun - Il blog di Matteo Casati</copyright><generator>Generated by feed.ASPItalia.com 'Weyoh' 4.8.825</generator><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><sy:updateBase>1998-01-01T12:00+00:00</sy:updateBase><image><title>Code and fun - Il blog di Matteo Casati</title><url>http://gui.aspitalia.com/images/aspitalia_syndication.gif</url><link>http://blogs.aspitalia.com/matteo/</link></image><item><title>L'ordine dei parametri in alcune classi del framework</title><link>http://blogs.aspitalia.com/matteo/post2365/Lordine-Parametri-Classi-Framework.aspx</link><pubDate>Thu, 21 Aug 2008 16:47:14 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2365' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;...&amp;#232; deciso in modo casuale???&lt;/p&gt; &lt;p&gt;Qualcuno mi spiega perch&amp;#233; &lt;a href="http://msdn.microsoft.com/en-us/library/sxykka64.aspx"&gt;ArgumentException(string, string)&lt;/a&gt; vuole prima il messaggio e poi il nome del parametro mentre, ad esempio, &lt;a href="http://msdn.microsoft.com/en-us/library/k8a0dfcy.aspx"&gt;ArgumentNullException(string, string)&lt;/a&gt; e &lt;a href="http://msdn.microsoft.com/en-us/library/wx2cdec8.aspx"&gt;ArgumentOutOfRangeException(string, string)&lt;/a&gt; funzionano al contrario (prima il nome del parametro e poi il messaggio?&lt;/p&gt; &lt;p&gt;Certe cose proprio non le capisco.&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post2365/Lordine-Parametri-Classi-Framework.aspx</guid><slash:comments>1</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post2365/Lordine-Parametri-Classi-Framework.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS2365.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2365</trackback:ping></item><item><title>The Developer Highway Code</title><link>http://blogs.aspitalia.com/matteo/post2364/The-Developer-Highway-Code.aspx</link><pubDate>Tue, 19 Aug 2008 12:19:18 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2364' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;A corollario dei miei due articoli sulla sicurezza delle applicazioni ASP.NET pubblicati in gennaio (&amp;quot;&lt;a href="http://www.aspitalia.com/articoli/asp.net2/aspnet-security.aspx"&gt;Realizzare applicazioni ASP.NET sicure - Prima parte&lt;/a&gt;&amp;quot; e &amp;quot;&lt;a href="http://www.aspitalia.com/articoli/asp.net2/aspnet-security-2.aspx"&gt;Realizzare applicazioni ASP.NET sicure - Seconda parte&lt;/a&gt;&amp;quot;) segnalo la possibilit&amp;#224; di scaricare &lt;strong&gt;gratuitamente&lt;/strong&gt; da &lt;a href="http://msdn.microsoft.com/en-gb/default.aspx"&gt;MSDN UK&lt;/a&gt; la versione digitale - e-book - dell'ottimo (seppur datato) &amp;quot;&lt;strong&gt;The Developer Highway Code&lt;/strong&gt;&amp;quot; di Paul Maher and Alex Mackman.&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-gb/security/aa473878.aspx"&gt;&lt;img height="243" alt="the developer highway code" src="http://blogs.aspitalia.com/img/m.casati/developerhighwaycode_bffb/the_developer_highway_code%20_5.jpg" width="174" border="0" /&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;L'ebook &amp;#232; disponibile all'indirizzo &lt;a href="http://msdn.microsoft.com/en-gb/security/aa473878.aspx"&gt;&lt;strong&gt;http://msdn.microsoft.com/en-gb/security/aa473878.aspx&lt;/strong&gt;&lt;/a&gt; (sia in formato PDF che XPS) ed &amp;#232; un aggiornamento della &lt;a href="http://www.amazon.com/developer-highway-code-paul-maher/dp/1905707584"&gt;copia edita da Microsft Press&lt;/a&gt; nel 2006.&lt;/p&gt; &lt;p&gt;&amp;#200; possibile scegliere di scaricare la versione completa (circa 7 MB per il PDF) oppure ogni singola sezione:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Part 1 &amp;#8211; Security Engineering &lt;/li&gt; &lt;li&gt;Part 2 &amp;#8211; Checklists and Question Lists &lt;/li&gt; &lt;li&gt;Part 3 &amp;#8211; What&amp;#8217;s New for Security in the .NET Framework v2.0 &lt;/li&gt; &lt;li&gt;Part 4 &amp;#8211; Microsoft Patterns &amp;amp; Practices Security Resources &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Buona lettura a tutti.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/ASP.NET/" rel="tag"&gt;ASP.NET&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET, ASP.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post2364/The-Developer-Highway-Code.aspx</guid><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post2364/The-Developer-Highway-Code.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS2364.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2364</trackback:ping></item><item><title>RollingList&amp;lt;T&amp;gt;</title><link>http://blogs.aspitalia.com/matteo/post2355/RollingListT.aspx</link><pubDate>Thu, 07 Aug 2008 08:22:00 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2355' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Nel &lt;a href="http://blogs.aspitalia.com/matteo/post2352/Semplice-MA-Apparenza-Collection-Generica.aspx"&gt;post precedente&lt;/a&gt; ho parlato di come utilizzare le classi di base del framework per realizzare una collection con le seguenti caratteristiche:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;all'inserimento di un nuovo elemento questo viene posizionato all'inizio della lista (i pi&amp;#249; recenti verranno visualizzati per primi) &lt;/li&gt;

  &lt;li&gt;la lista deve contenere al massimo &lt;em&gt;n&lt;/em&gt; elementi: l'inserimento di un nuovo elemento, raggiunto il limite &lt;em&gt;n&lt;/em&gt;, deve prevedere la rimozione dell'elemento pi&amp;#249; vecchio presente nella lista (ovvero quello inserito da pi&amp;#249; tempo) &lt;/li&gt;

  &lt;li&gt;garantire ottime performance &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="http://forum.aspitalia.com/forum/post/328680/Semplice-MA-Apparenza-Collection-Generica.aspx"&gt;Il commento di rsaccav&lt;/a&gt;&lt;/strong&gt; mi ha fatto convinto ad implementare una collezione generica &amp;quot;&lt;em&gt;from scratch&lt;/em&gt;&amp;quot;, cos&amp;#236; da colmare il vuoto lasciato in System.Collection.Generic.&lt;/p&gt;

&lt;p&gt;Con estrema fantasia l'ho battezzata &lt;strong&gt;RollingList&amp;lt;T&amp;gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Il principio &amp;#232; piuttosto semplice: la lista si basa su un &lt;strong&gt;array con dimensione fissa&lt;/strong&gt; pari al limite di elementi da conservare (&lt;strong&gt;Capacity&lt;/strong&gt;; la propriet&amp;#224; deve essere impostata nel costruttore o comunque *prima* dell'inserimento del primo elemento) associato ad un &lt;strong&gt;cursore&lt;/strong&gt; (backward) che definisce la posizione di inserimento/sostituzione e che consente di enumerare gli elementi nell'ordine corretto.&lt;/p&gt;

&lt;p&gt;Il codice completo della classe:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;using System; 
    &lt;br /&gt;using System.Collections; 

    &lt;br /&gt;using System.Threading; 

    &lt;br /&gt;

    &lt;br /&gt;public class RollingList&amp;lt;T&amp;gt; : ICollection 

    &lt;br /&gt;{&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private int _cursor; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private int _size; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private int _capacity; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private T[] _items;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; private object _syncRoot;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public RollingList(int capacity) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; {&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Capacity = capacity;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } 

    &lt;br /&gt;&lt;/code&gt;&lt;code&gt;
    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public int Capacity 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return _capacity; } 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; set 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (value &amp;lt;= 0) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new ArgumentOutOfRangeException(&amp;quot;value&amp;quot;, &amp;quot;Capacity must be greater than zero&amp;quot;); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_capacity &amp;gt; 0) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new ArgumentException(&amp;quot;Capacity has just been defined&amp;quot;, &amp;quot;value&amp;quot;); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _capacity = value; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _items = new T[_capacity]; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _cursor = (_capacity - 1); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160;&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void Add(T item) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_capacity &amp;lt;= 0) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; throw new NotSupportedException(&amp;quot;Capacity is not greater than zero&amp;quot;); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _items[_cursor--] = item; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_size &amp;lt; _capacity) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _size++; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_cursor &amp;lt; 0) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _cursor = (_capacity - 1); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void Clear() 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Array.Clear(_items, 0, _size); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _size = 0; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _cursor = (_capacity - 1); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public T[] ToArray() 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; T[] destinationArray = new T[_size];&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_size == 0) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return destinationArray; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; int cursorPosition = (_cursor + 1 == _capacity) ? 0 : _cursor + 1; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Array.Copy(_items, cursorPosition, destinationArray, 0, (_capacity - cursorPosition)); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_size == _capacity &amp;amp;&amp;amp; cursorPosition &amp;gt; 0) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Array.Copy(_items, 0, destinationArray, (_capacity - cursorPosition), cursorPosition); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return destinationArray; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } 

    &lt;br /&gt;&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public void CopyTo(Array array, int index) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Array.Copy(ToArray(), 0, array, index, _size); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public int Count 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return _size; } 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public bool IsSynchronized 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get { return false; } 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public object SyncRoot 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; get 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; if (_syncRoot == null) 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Interlocked.CompareExchange(ref _syncRoot, new object(), null); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; } 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return _syncRoot; 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; }&amp;#160; &lt;br /&gt;

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; public IEnumerator GetEnumerator() 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; { 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return ToArray().GetEnumerator(); 

    &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; } 

    &lt;br /&gt;}&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Questa implementazione &amp;#232; sicuramente migliorabile (ad esempio, oltre a &lt;em&gt;ICollection&lt;/em&gt; potrebbe essere utile implementare l'interfaccia &lt;em&gt;ICollection&amp;lt;T&amp;gt;&lt;/em&gt;, supportare la serializzazione, ecc.) ma &amp;#232; decisamente preferibile rispetto all'uso di Stack&amp;lt;T&amp;gt;, Queue&amp;lt;T&amp;gt; o LinkedList&amp;lt;T&amp;gt; in quanto:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&amp;#160;&lt;strong&gt;semplifica il codice di inserimento&lt;/strong&gt; di elementi (le operazioni di IN/OUT al raggiungimento della capacit&amp;#224; massima definita sono gestite dalla collection stessa, quindi non richiedono codice di controllo aggiuntivo) &lt;/li&gt;

  &lt;li&gt;&lt;strong&gt;semplifica la lettura&lt;/strong&gt; grazie ad una corretta enumerazione nativa degli elementi &lt;/li&gt;

  &lt;li&gt;permette di avere &lt;strong&gt;performance notevolmente pi&amp;#249; elevate&lt;/strong&gt;: &lt;/li&gt;
&lt;/ol&gt;
&lt;code&gt;// 
  &lt;br /&gt;// RollingList performance test 

  &lt;br /&gt;// 

  &lt;br /&gt;int capacity = 10000; 

  &lt;br /&gt;int max = 1000000000; 

  &lt;br /&gt;DateTime start = DateTime.Now; 

  &lt;br /&gt;RollingList&amp;lt;int&amp;gt; list = new RollingList&amp;lt;int&amp;gt;(capacity); 

  &lt;br /&gt;for (int i = 1; i &amp;lt;= max; i++) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; list.Add(i); 

  &lt;br /&gt;} 

  &lt;br /&gt;foreach (int item in list) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // do something with &amp;quot;item&amp;quot; 

  &lt;br /&gt;} 

  &lt;br /&gt;Console.WriteLine(&amp;quot;RollingList: max={0} -&amp;gt; {1}&amp;quot;, 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; max.ToString(&amp;quot;#,###&amp;quot;), 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DateTime.Now.Subtract(start)); &lt;/code&gt;

&lt;p&gt;Produce: &lt;/p&gt;

&lt;p&gt;RollingList: max=1.000.000.000 -&amp;gt; 00:00:11.5610000&lt;/p&gt;

&lt;p&gt;Ovvero un tempo di esecuzione che &amp;#232; circa &lt;strong&gt;un terzo&lt;/strong&gt; rispetto a Queue&amp;lt;T&amp;gt;!!!&lt;/p&gt;

&lt;p&gt;HTH&lt;/p&gt;
&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post2355/RollingListT.aspx</guid><slash:comments>9</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post2355/RollingListT.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS2355.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2355</trackback:ping></item><item><title>Una semplice (ma solo in apparenza) collection generica</title><link>http://blogs.aspitalia.com/matteo/post2352/Semplice-MA-Apparenza-Collection-Generica.aspx</link><pubDate>Thu, 31 Jul 2008 13:34:55 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2352' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Nel progetto (Web) a cui sto lavorando &amp;#232; stata richiesta la visualizzazione di una lista di elementi con le seguenti caratteristiche:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;i nuovi elementi devono essere inseriti all'inizio dell'elenco (i pi&amp;#249; recenti verranno visualizzati per primi) &lt;/li&gt;

  &lt;li&gt;la lista deve contenere al massimo &lt;em&gt;n&lt;/em&gt; elementi: l'inserimento di un nuovo elemento, raggiunto il limite &lt;em&gt;n&lt;/em&gt;, deve prevedere la rimozione dell'elemento pi&amp;#249; vecchio presente nella lista (ovvero quello inserito da pi&amp;#249; tempo) &lt;/li&gt;

  &lt;li&gt;l'aggiunta di nuovi elementi &amp;#232; corposa (centinaia di insert al secondo per tutto il ciclo di vita dell'applicazione) &lt;/li&gt;

  &lt;li&gt;il limite del numero massimo di elementi che devono essere mantenuti nella lista (&lt;em&gt;n&lt;/em&gt;) &amp;#232; relativamente basso (&amp;lt; 10.000) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In pratica, definito un limite di 3 elementi e immaginando l'accodamento dei primi 5 interi in ordine crescente (1, 2, 3, 4 e 5) il risultato atteso &amp;#232;:&lt;/p&gt;
1 

&lt;br /&gt;2 1 

&lt;br /&gt;3 2 1 

&lt;br /&gt;4 3 2 

&lt;br /&gt;5 4 3 

&lt;p&gt;Ho pensato che sia una cosa semplicissima da realizzare in .NET sfruttando le classi in System.Collection.Generic ma... quale usare? Il framework prevede infatti:&lt;/p&gt;

&lt;h3&gt;List&amp;lt;T&amp;gt; &lt;/h3&gt;

&lt;p&gt;Lista generica, non utilizzabile allo scopo in quanto non &amp;#232; possibile inserire elementi in posizioni specifiche ma solo &amp;quot;to the end of the List(T)&amp;quot;.&lt;/p&gt;

&lt;p&gt;In realt&amp;#224; sarebbe possibile effettuare l'inserimento all'inizio della lista effettuando uno shift di tutti gli elementi ma le performance sarebbero improponibili!&lt;/p&gt;

&lt;h3&gt;Stack&amp;lt;T&amp;gt;&lt;/h3&gt;

&lt;p&gt;&amp;#200; letteralmente un insieme di elementi &amp;quot;impilati&amp;quot;; possiamo vederlo come una vaschetta portadocumenti sulla scrivania in cui vengono aggiunte delle pratiche (Push) semplicemente appoggiandole sopra e con l'impiegato che le processa che prende (Pop) il primo foglio che trova in cima alla pigna. Non assolve dunque allo scopo in quanto rimuove gli elementi pi&amp;#249; &amp;quot;nuovi&amp;quot; anzich&amp;#233; quelli pi&amp;#249; &amp;quot;vecchi&amp;quot;.&lt;/p&gt;

&lt;p&gt;In pratica il seguente codice:&lt;/p&gt;
&lt;code&gt;int capacity = 3; 
  &lt;br /&gt;int max = 5; 

  &lt;br /&gt;Stack&amp;lt;int&amp;gt; list = new Stack&amp;lt;int&amp;gt;(capacity); 

  &lt;br /&gt;for (int i = 1; i &amp;lt;= max; i++) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (list.Count &amp;gt;= capacity) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; list.Pop(); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; list.Push(i); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var item in list) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.Write(&amp;quot;{0} &amp;quot;, item); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(); 

  &lt;br /&gt;}&lt;/code&gt; 

&lt;p&gt;Produce:&lt;/p&gt;

&lt;p&gt;1 
  &lt;br /&gt;2 1 

  &lt;br /&gt;3 2 1 

  &lt;br /&gt;4 2 1 

  &lt;br /&gt;5 2 1&lt;/p&gt;

&lt;p&gt;Non ci siamo.&lt;/p&gt;

&lt;h3&gt;Queue&amp;lt;T&amp;gt;&lt;/h3&gt;

&lt;p&gt;&amp;#200; appunto una &amp;quot;coda&amp;quot; dove il primo elemento inserito (Enqueue) &amp;#232; anche il primo a venire rimosso (Dequeue); l'analogia che mi viene in mente &amp;#232; quella delle macchine ferme al casello dell'autostrada: il primo arrivato sar&amp;#224; anche il primo a superare la barriera. Questa collection assolve per met&amp;#224; allo scopo garantendo il corretto meccanismo di in/out ma ha il contro di presentare l'enumerazione degli elementi in ordine inverso rispetto a quanto richiesto (scorrendo la collection ottengo prima gli elementi pi&amp;#249; &amp;quot;vecchi&amp;quot; e poi quelli pi&amp;#249; &amp;quot;nuovi&amp;quot;)&lt;/p&gt;

&lt;p&gt;In pratica il seguente codice:&lt;/p&gt;
&lt;code&gt;int capacity = 3; 
  &lt;br /&gt;int max = 5; 

  &lt;br /&gt;Queue&amp;lt;int&amp;gt; list = new Queue&amp;lt;int&amp;gt;(capacity); 

  &lt;br /&gt;for (int i = 1; i &amp;lt;= max; i++) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (list.Count &amp;gt;= capacity) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; list.Dequeue(); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; list.Enqueue(i); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var item in list) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.Write(&amp;quot;{0} &amp;quot;, item); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(); 

  &lt;br /&gt;}&lt;/code&gt; 

&lt;p&gt;Produce:&lt;/p&gt;

&lt;p&gt;1 
  &lt;br /&gt;1 2 

  &lt;br /&gt;1 2 3 

  &lt;br /&gt;2 3 4 

  &lt;br /&gt;3 4 5&lt;/p&gt;

&lt;p&gt;Non ci siamo ancora ma manca poco :-)&lt;/p&gt;

&lt;h3&gt;LinkedList&amp;lt;T&amp;gt;&lt;/h3&gt;

&lt;p&gt;Si tratta di un elenco con doppio collegamento; espone metodi per l'inserimento di nuovi elementi sia all'inizio dell'elenco (AddFirst) che alla fine (AddLast) che in posizioni intermedie (AddAfter e AddBefore), sia per la rimozione (RemoveFirst, RemoveLast, Remove), dandoci la massima flessibilit&amp;#224; possibile. In pratica possiamo immaginare questa collection come un trenino giocattolo: possiamo aggiungere o togliere vagoni da entrambe le estremit&amp;#224; del convoglio in modo del tutto indifferente.&lt;/p&gt;

&lt;p&gt;In pratica il seguente codice:&lt;/p&gt;
&lt;code&gt;int capacity = 3; 
  &lt;br /&gt;int max = 5; 

  &lt;br /&gt;LinkedList&amp;lt;int&amp;gt; list = new LinkedList&amp;lt;int&amp;gt;(); 

  &lt;br /&gt;for (int i = 1; i &amp;lt;= max; i++) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (list.Count &amp;gt;= capacity) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; list.RemoveLast(); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; list.AddFirst(i); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; foreach (var item in list) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; Console.Write(&amp;quot;{0} &amp;quot;, item); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; Console.WriteLine(); 

  &lt;br /&gt;}&lt;/code&gt; 

&lt;p&gt;Produce:&lt;/p&gt;

&lt;p&gt;1 
  &lt;br /&gt;2 1 

  &lt;br /&gt;3 2 1 

  &lt;br /&gt;4 3 2 

  &lt;br /&gt;5 4 3&lt;/p&gt;

&lt;p&gt;Missione compiuta? Sembrerebbe di s&amp;#236;.&lt;/p&gt;

&lt;p&gt;Per scrupolo ho fatto un piccolo test di performance, aspettandomi prestazioni simili per Queue e LinkedList:&lt;/p&gt;
&lt;code&gt;// 
  &lt;br /&gt;// Performance test configuration 

  &lt;br /&gt;// 

  &lt;br /&gt;DateTime start; 

  &lt;br /&gt;int[] results; 

  &lt;br /&gt;int capacity = 10000; 

  &lt;br /&gt;int max = 1000000000; 

  &lt;br /&gt;

  &lt;br /&gt;// 

  &lt;br /&gt;// LinkedList performance test 

  &lt;br /&gt;// 

  &lt;br /&gt;start = DateTime.Now; 

  &lt;br /&gt;LinkedList&amp;lt;int&amp;gt; list = new LinkedList&amp;lt;int&amp;gt;(); 

  &lt;br /&gt;for (int i = 1; i &amp;lt;= max; i++) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (list.Count &amp;gt;= capacity) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; list.RemoveLast(); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; list.AddFirst(i); 

  &lt;br /&gt;} 

  &lt;br /&gt;results = new int[list.Count]; 

  &lt;br /&gt;list.CopyTo(results, 0); 

  &lt;br /&gt;foreach (int item in results) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // do something with &amp;quot;item&amp;quot; 

  &lt;br /&gt;} 

  &lt;br /&gt;Console.WriteLine(&amp;quot;LinkedList: max={0} -&amp;gt; {1}&amp;quot;, 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; max.ToString(&amp;quot;#,###&amp;quot;), 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DateTime.Now.Subtract(start)); 

  &lt;br /&gt;

  &lt;br /&gt;// 

  &lt;br /&gt;// Queue performance test 

  &lt;br /&gt;// 

  &lt;br /&gt;start = DateTime.Now; 

  &lt;br /&gt;results = null; 

  &lt;br /&gt;Queue&amp;lt;int&amp;gt; queue = new Queue&amp;lt;int&amp;gt;(capacity); 

  &lt;br /&gt;for (int i = 1; i &amp;lt;= max; i++) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; if (queue.Count &amp;gt;= capacity) 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; queue.Dequeue(); 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; queue.Enqueue(i); 

  &lt;br /&gt;} 

  &lt;br /&gt;results = queue.ToArray(); 

  &lt;br /&gt;foreach (int item in results) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // do something with &amp;quot;item&amp;quot; 

  &lt;br /&gt;} 

  &lt;br /&gt;Console.WriteLine(&amp;quot;Queue: max={0} -&amp;gt; {1}&amp;quot;, 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; max.ToString(&amp;quot;#,###&amp;quot;), 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; DateTime.Now.Subtract(start));&lt;/code&gt; 

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Sebbene questo tipo di misurazione sia piuttosto &amp;quot;spannometrico&amp;quot;, il risultato (per un miliardo di inserimenti a fronte di una lista con al pi&amp;#249; 10.000 items) mi ha lasciato basito:&lt;/p&gt;

&lt;p&gt;LinkedList: max=1.000.000.000 -&amp;gt; 00:01:17.6770000 
  &lt;br /&gt;Queue: max=1.000.000.000 -&amp;gt; 00:00:30.4030000&lt;/p&gt;

&lt;p&gt;Ovvero LinkedList richiede circa 2.5 volte il tempo necessario a Queue!&lt;/p&gt;

&lt;h3&gt;Conclusioni&lt;/h3&gt;

&lt;p&gt;Sebbene LinkedList&amp;lt;T&amp;gt; faccia il suo &amp;quot;sporco lavoro&amp;quot; lo fa... &lt;strong&gt;troppo lentamente!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alla fine ho dunque optato per l'utilizzo di Queue&amp;lt;T&amp;gt; con l'aggiunta di poche righe di codice per leggere in modo inverso il contenuto enumerato della lista:&lt;/p&gt;
&lt;code&gt;Queue&amp;lt;int&amp;gt; queue = new Queue&amp;lt;int&amp;gt;(capacity); 
  &lt;br /&gt;// (codice omesso) 

  &lt;br /&gt;List&amp;lt;int&amp;gt; temp = new List&amp;lt;int&amp;gt;(queue.ToArray()); 

  &lt;br /&gt;temp.Reverse(); 

  &lt;br /&gt;results = temp.ToArray(); 

  &lt;br /&gt;foreach (int item in results) 

  &lt;br /&gt;{ 

  &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; // do something with &amp;quot;item&amp;quot; 

  &lt;br /&gt;}&lt;/code&gt; 

&lt;p&gt;Infatti il numero di elementi mantenuti nella coda &amp;#232; decisamente troppo basso - meno di 10.000 - per risultare influenti le operazioni di copia in una List e di reverse della lista, anche se molto probabilmente questa porzione di codice potrebbe essere migliorata :-)&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;PS 1: qualcuno avr&amp;#224; notato l'assenza di acronimi come FIFO (first-in, first-out), LIFO (last-in, first-out), ecc. 
  &lt;br /&gt;Sono stati volutamente omessi perch&amp;#233; il significato di &amp;quot;primo&amp;quot; e &amp;quot;ultimo&amp;quot; mi &amp;#232; risultato, leggendo qua e l&amp;#224; sul Web, interpretato in modo non del tutto univoco (si riferisce all'ordine di inserimento? alla posizione che assume l'elemento nella collection? ad altro?)&lt;/p&gt;

&lt;p&gt;PS 2: un doveroso grazie a &lt;a href="http://blogs.aspitalia.com/ricciolo/"&gt;Cristian&lt;/a&gt; e a &lt;a href="http://blogs.aspitalia.com/nostromo/"&gt;Marco&lt;/a&gt; che mi hanno &lt;strike&gt;supportato&lt;/strike&gt; sopportato in questa ricerca&lt;/p&gt;
&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post2352/Semplice-MA-Apparenza-Collection-Generica.aspx</guid><slash:comments>15</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post2352/Semplice-MA-Apparenza-Collection-Generica.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS2352.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2352</trackback:ping></item><item><title>IDictionary e la serializzazione in XML</title><link>http://blogs.aspitalia.com/matteo/post2330/IDictionary-Serializzazione-XML.aspx</link><pubDate>Thu, 17 Jul 2008 12:26:00 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2330' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Chi lavora con i Web Service si sarà accorto che le strutture chiave/valore (Hashtable, Dictionary generici o specializzati, ecc.), non implementando l'interfaccia &lt;a title="IXmlSerializable" href="http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx"&gt;IXmlSerializable&lt;/a&gt; risultano &amp;quot;intrasportabili&amp;quot;.&lt;/p&gt;&lt;p&gt;Qualcuno ci ha anche &lt;a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=95599"&gt;provato a chiedere a Microsoft&lt;/a&gt; di modificare questo comportamento ma la risposta è stata &amp;quot;Won't fix&amp;quot;... La motivazione? Semplice: &amp;quot;&lt;em&gt;Unfortunately, we cannot change Dictionary&amp;lt;K,V&amp;gt; to implement IXmlSerializable since it is located in the mscorlib assembly that cannot reference System.Xml.dll.&lt;/em&gt;&amp;quot;&lt;/p&gt;&lt;p&gt;In realtà creare un Dictionary generico serializzabile in XML è piuttosto semplice: basta creare una classe &amp;quot;SerializableDictionary&amp;quot; che derivi da Dictionary&amp;lt;TKey, TValue&amp;gt; e implementi IXmlSerializable, serializzando - per ogni KeyValuePair contenuto nella collection di base - sia la chiave che il valore.&lt;/p&gt;&lt;p&gt;Ho fatto due implementazioni: la prima serializza le chiavi e i valori in Base64, la seconda in XML.&lt;/p&gt;&lt;h3&gt;KeyValuePair in Base64&lt;/h3&gt;&lt;p&gt;using System;&lt;br /&gt;using System.IO;&lt;br /&gt;using System.Xml;&lt;br /&gt;using System.Xml.Schema;&lt;br /&gt;using System.Xml.Serialization;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Runtime.Serialization.Formatters;&lt;br /&gt;using System.Runtime.Serialization.Formatters.Binary; &lt;/p&gt;&lt;p&gt;[Serializable]&lt;br /&gt;public class SerializableDictionary&amp;lt;TKey, TValue&amp;gt; : Dictionary&amp;lt;TKey, TValue&amp;gt;, IXmlSerializable&lt;br /&gt;{&lt;br /&gt;    #region IXmlSerializable Members &lt;/p&gt;&lt;p&gt;    private const string NS = &amp;quot;&amp;quot;;&lt;br /&gt;    private const string XML_ITEM_NODE_NAME = &amp;quot;item&amp;quot;;&lt;br /&gt;    private const string XML_KEY_ATTRIBUTE_NAME = &amp;quot;key&amp;quot;;&lt;br /&gt;    private const string XML_VALUE_ATTRIBUTE_NAME = &amp;quot;value&amp;quot;; &lt;/p&gt;&lt;p&gt;    public XmlSchema GetSchema()&lt;br /&gt;    {&lt;br /&gt;        return null;&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    public void WriteXml(XmlWriter w)&lt;br /&gt;    {&lt;br /&gt;        foreach (TKey key in Keys)&lt;br /&gt;        {&lt;br /&gt;            TValue value = this[key];&lt;br /&gt;            w.WriteStartElement(XML_ITEM_NODE_NAME, NS);&lt;br /&gt;            w.WriteElementString(XML_KEY_ATTRIBUTE_NAME, NS, ToBase64(key));&lt;br /&gt;            w.WriteElementString(XML_VALUE_ATTRIBUTE_NAME, NS, ToBase64(value));&lt;br /&gt;            w.WriteEndElement();&lt;br /&gt;        }&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    public void ReadXml(XmlReader r)&lt;br /&gt;    {&lt;br /&gt;        r.Read();&lt;br /&gt;        r.MoveToContent();&lt;br /&gt;        while (r.NodeType != XmlNodeType.EndElement)&lt;br /&gt;        {&lt;br /&gt;            r.ReadStartElement(XML_ITEM_NODE_NAME, NS);&lt;br /&gt;            TKey key = FromBase64&amp;lt;TKey&amp;gt;(r.ReadElementString(XML_KEY_ATTRIBUTE_NAME, NS));&lt;br /&gt;            TValue value = FromBase64&amp;lt;TValue&amp;gt;(r.ReadElementString(XML_VALUE_ATTRIBUTE_NAME, NS));&lt;br /&gt;            r.ReadEndElement();&lt;br /&gt;            r.MoveToContent();&lt;br /&gt;            Add(key, value);&lt;br /&gt;        }&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    #endregion &lt;/p&gt;&lt;p&gt;    #region Base64 Serialization &lt;/p&gt;&lt;p&gt;    private static string ToBase64(object value)&lt;br /&gt;    {&lt;br /&gt;        using (MemoryStream stream = new MemoryStream())&lt;br /&gt;        {&lt;br /&gt;            BinaryFormatter formatter = new BinaryFormatter();&lt;br /&gt;            formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;&lt;br /&gt;            formatter.Serialize(stream, value);&lt;br /&gt;            byte[] buffer = stream.ToArray();&lt;br /&gt;            return Convert.ToBase64String(buffer, 0, buffer.Length, Base64FormattingOptions.None);&lt;br /&gt;        }&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    public static T FromBase64&amp;lt;T&amp;gt;(string base64)&lt;br /&gt;    {&lt;br /&gt;        byte[] buffer = Convert.FromBase64String(base64);&lt;br /&gt;        using (MemoryStream stream = new MemoryStream(buffer))&lt;br /&gt;        {&lt;br /&gt;            BinaryFormatter formatter = new BinaryFormatter();&lt;br /&gt;            formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;&lt;br /&gt;            return (T)formatter.Deserialize(stream);&lt;br /&gt;        }&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    #endregion&lt;br /&gt;} &lt;/p&gt;&lt;h3&gt;KeyValuePair in XML&lt;/h3&gt;&lt;p&gt;using System;&lt;br /&gt;using System.Xml;&lt;br /&gt;using System.Xml.Schema;&lt;br /&gt;using System.Xml.Serialization;&lt;br /&gt;using System.Collections.Generic; &lt;/p&gt;&lt;p&gt;[Serializable]&lt;br /&gt;public class SerializableDictionary&amp;lt;TKey, TValue&amp;gt; : Dictionary&amp;lt;TKey, TValue&amp;gt;, IXmlSerializable&lt;br /&gt;{&lt;br /&gt;    #region IXmlSerializable Members &lt;/p&gt;&lt;p&gt;    private const string NS = &amp;quot;&amp;quot;;&lt;br /&gt;    private const string XML_ITEM_NODE_NAME = &amp;quot;item&amp;quot;;&lt;br /&gt;    private const string XML_KEY_NODE_NAME = &amp;quot;key&amp;quot;;&lt;br /&gt;    private const string XML_VALUE_NODE_NAME = &amp;quot;value&amp;quot;; &lt;/p&gt;&lt;p&gt;    public XmlSchema GetSchema()&lt;br /&gt;    {&lt;br /&gt;        return null;&lt;br /&gt;    }&lt;br /&gt;    public void ReadXml(XmlReader reader)&lt;br /&gt;    {&lt;br /&gt;        XmlSerializer ks = new XmlSerializer(typeof(TKey));&lt;br /&gt;        XmlSerializer vs = new XmlSerializer(typeof(TValue));&lt;br /&gt;        bool wasEmpty = reader.IsEmptyElement;&lt;br /&gt;        reader.Read();&lt;br /&gt;        if (wasEmpty)&lt;br /&gt;            return;&lt;br /&gt;        while (reader.NodeType != XmlNodeType.EndElement)&lt;br /&gt;        {&lt;br /&gt;            reader.ReadStartElement(XML_ITEM_NODE_NAME, NS);&lt;br /&gt;            reader.ReadStartElement(XML_KEY_NODE_NAME, NS);&lt;br /&gt;            TKey key = (TKey)ks.Deserialize(reader);&lt;br /&gt;            reader.ReadEndElement();&lt;br /&gt;            reader.ReadStartElement(XML_VALUE_NODE_NAME, NS);&lt;br /&gt;            TValue value = (TValue)vs.Deserialize(reader);&lt;br /&gt;            reader.ReadEndElement();&lt;br /&gt;            Add(key, value);&lt;br /&gt;            reader.ReadEndElement();&lt;br /&gt;            reader.MoveToContent();&lt;br /&gt;        }&lt;br /&gt;        reader.ReadEndElement();&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    public void WriteXml(XmlWriter writer)&lt;br /&gt;    {&lt;br /&gt;        XmlSerializer ks = new XmlSerializer(typeof(TKey));&lt;br /&gt;        XmlSerializer vs = new XmlSerializer(typeof(TValue));&lt;br /&gt;        foreach (TKey key in Keys)&lt;br /&gt;        {&lt;br /&gt;            writer.WriteStartElement(XML_ITEM_NODE_NAME, NS);&lt;br /&gt;            writer.WriteStartElement(XML_KEY_NODE_NAME, NS);&lt;br /&gt;            ks.Serialize(writer, key);&lt;br /&gt;            writer.WriteEndElement();&lt;br /&gt;            writer.WriteStartElement(XML_VALUE_NODE_NAME, NS);&lt;br /&gt;            TValue value = this[key];&lt;br /&gt;            vs.Serialize(writer, value);&lt;br /&gt;            writer.WriteEndElement();&lt;br /&gt;            writer.WriteEndElement();&lt;br /&gt;        }&lt;br /&gt;    } &lt;/p&gt;&lt;p&gt;    #endregion&lt;br /&gt;} &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;A voi la scelta :-)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Web_Service/" rel="tag"&gt;Web Service&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/XML/" rel="tag"&gt;XML&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET, .NET Framework, Web Service, XML</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post2330/IDictionary-Serializzazione-XML.aspx</guid><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post2330/IDictionary-Serializzazione-XML.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS2330.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2330</trackback:ping></item><item><title>3-Tier, 3-Layer e MVC: ma sono la stessa cosa?</title><link>http://blogs.aspitalia.com/matteo/post2318/3Tier-3Layer-MVC-Cosa.aspx</link><pubDate>Thu, 10 Jul 2008 15:46:00 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=2318' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Questa riflessione parte dalla domanda di un utente nel forum:&lt;/p&gt;&lt;cite&gt;&amp;quot;&lt;a href="http://forum.aspitalia.com/forum/post/326672/Domanda-Analogie-MVC-Threetier.aspx"&gt;Domanda: Analogie tra MVC e Three-tier&lt;/a&gt; - Sono troppe e a me sembra che l'uno possa sostituire l'altro.. ma quanto sbaglio?&amp;quot;&lt;/cite&gt; &lt;p&gt;Ho l'impressione che questa perplessità sia parecchio diffusa e che, più in generale, ci sia parecchia confusione quando si parla di software architecture: spero che questo post possa chiarire un po' meglio alcuni concetti.&lt;/p&gt;&lt;p&gt;Iniziamo definendo, in termini strettamente lessicali, cosa si intende per &amp;quot;3-Tier&amp;quot;, dato che la stessa Wikipedia non è affatto chiara nè precisa (sia in &lt;a href="http://it.wikipedia.org/wiki/Architettura_three-tier"&gt;italiano&lt;/a&gt; che in &lt;a href="http://en.wikipedia.org/wiki/Three-tier_%28computing%29"&gt;inglese&lt;/a&gt;) contribuendo ad aumentare la confusione.&lt;/p&gt;&lt;h2&gt;Architettura 3-Tier (o n-Tier)&lt;/h2&gt;&lt;p&gt;Letteralmente si parla di &amp;quot;architetture a 3 o più livelli&amp;quot; per definire un modello che fornisca una &lt;b&gt;separazione fisica&lt;/b&gt; dell'applicazione; in pratica si dice che un'applicazione può essere erogata usando un'infrastruttura complessa e diversificata, tipicamente usando più server, ciascuno dedicato ad una funzionalità specifica (fron-end, middleware, back-end, ecc.)&lt;br /&gt;Una spiegazione più dettagliata di questo modello distributivo è disponibile sul sito &amp;quot;Microsoft patterns &amp;amp; practices Developer Center&amp;quot;: &lt;a href="http://msdn.microsoft.com/en-us/library/ms978694.aspx"&gt;Three-Tiered Distribution&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In pratica ritengo che si dovrebbe parlare di &amp;quot;tier&amp;quot; in riferimento a qualcosa di &amp;quot;sistemistico&amp;quot;, e non per architettura software in senso stretto.&lt;/p&gt;&lt;h2&gt;Architettura 3-Layer (o n-Layer)&lt;/h2&gt;&lt;p&gt;Le architetture a 3 strati (o più: il &amp;quot;3&amp;quot; è entrato nella concezione comune in quanto rappresenta la stratificazione più semplice ed utilizzata) sono un modello di organizzazione del codice applicativo basato sulla separazione delle funzionalità logiche. Tipicamente avremo:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Presentation (PL)&lt;/b&gt;: la visualizzazione dei dati e, più in generale, la rappresentazione dei controlli (forms, controlli di input, labels, ecc.) necessari per l'interfaccia utente &lt;/li&gt;&lt;li&gt;&lt;b&gt;Business Logic (BLL)&lt;/b&gt;: rappresenta la parte principale dell'applicazione, definendo il &lt;b&gt;domain model&lt;/b&gt; dell'applicazione, ovvero le entità (ad esempio: fattura, cliente, ecc.), le loro relazioni e le logiche applicative. Non deve contenere contenere alcun riferimento a come i dati saranno presentati all'utente o a come verranno salvati &lt;/li&gt;&lt;li&gt;&lt;b&gt;Data Access (DAL)&lt;/b&gt;: contiene tutto quello che concerne la persistenza dei dati (database, tabelle, record, file system, ecc.) &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Questo tipo di architettura ha principalmente il vantaggio di fornire una &lt;b&gt;separazione logica&lt;/b&gt; così da aumentarne la manutenibilità, la scalabilità ed il riutilizzo.&lt;br /&gt;Una spiegazione più dettagliata di questo tipo di architettura è disponibile sul sito &amp;quot;Microsoft patterns &amp;amp; practices Developer Center&amp;quot;: &lt;a href="http://msdn.microsoft.com/en-us/library/ms978689.aspx"&gt;Three-Layered Services Application&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Model-View-Controller (MVC)&lt;/h2&gt;&lt;p&gt;Questo pattern, introdotto solo di recente nel mondo .NET ma diffuso da tempo in altri ambienti, fornisce un modello per strutturare in modo organizzato le funzionalità relative alla UI e orchestrare l'accesso agli altri strati applicativi (BLL e DAL):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Model&lt;/b&gt;: è l'insieme dei componenti che mantengono lo &amp;quot;stato&amp;quot;: i dati e i metodi per accedervi. In pratica costituisce la logica applicativa o - IMHO preferibilmente - l'accesso al layer (separato) di BL &lt;/li&gt;&lt;li&gt;&lt;b&gt;View&lt;/b&gt;: deputato alla visualizzazione vera e propria dell'interfaccia utente per la presentazione dei dati &lt;/li&gt;&lt;li&gt;&lt;b&gt;Controller&lt;/b&gt;: gestisce le interazioni dell'utente con l'applicazione (tipicamente intercettando e gestendo gli eventi e gli input dell'utente), mediante accesso al Model e definendo la View corrispondente da presentare &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;MVC non contraddice quindi il modello 3-Layer, semplicemente è una delle possibili implementazioni di questo tipo di architettura; da un certo punto di vista possiamo addirittura vedere MVC come un'estensione dell'architettura a 3 strati, in quanto porta una separazione logica ulteriore nel livello di presentation.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;MVC è dunque un'alternativa ai Web Forms di ASP.NET&lt;/strong&gt; e, come tale, ha vantaggi e svantaggi. &lt;/p&gt;&lt;p&gt;Per quanto mi riguarda (non ne faccio mistero: il modello a forms ASP.NET non mi è mai piaciuto per tanti motivi) MVC ha solo vantaggi :-)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/Architettura/" rel="tag"&gt;Architettura&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/ASP.NET/" rel="tag"&gt;ASP.NET&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET, .NET Framework, Architettura, ASP.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post2318/3Tier-3Layer-MVC-Cosa.aspx</guid><slash:comments>1</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post2318/3Tier-3Layer-MVC-Cosa.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS2318.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=2318</trackback:ping></item><item><title>Anonymous Methods e collection generiche</title><link>http://blogs.aspitalia.com/matteo/post1851/Anonymous-Methods-Collection-Generiche.aspx</link><pubDate>Tue, 21 Nov 2006 17:26:06 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=1851' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Tutto quello che ci serve sapere per &lt;a title="managing collections with functors" href="http://dotnetslackers.com/community/blogs/simoneb/archive/2006/08/20/367.aspx"&gt;lavorare con le collection generiche usando anonymous methods&lt;/a&gt;; purtroppo è in lingua inglese... ma se insistiamo tutti insieme magari &lt;a title="simoneb's blog" href="http://dotnetslackers.com/community/blogs/simoneb/"&gt;Simone&lt;/a&gt; lo traduce e lo posta anche sul &lt;a href="http://blogs.ugidotnet.org/simone%20busoli"&gt;suo blog italiano&lt;/a&gt; o su &lt;a title="guru4.net" href="http://www.guru4.net/"&gt;GURU4.net&lt;/a&gt; ;-)&lt;/p&gt; &lt;p&gt;L'articolo è un po' datato ma - per chi non l'avesse ancora visto - credo valga la pena spendere 10 minuti per risparmiare qualche ora al momento del bisogno :-)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;a href="http://tags.aspitalia.com/.NET_Framework/" rel="tag"&gt;.NET Framework&lt;/a&gt;, &lt;a href="http://tags.aspitalia.com/.NET_Framework_2.0/" rel="tag"&gt;.NET Framework 2.0&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET, .NET Framework, .NET Framework 2.0</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post1851/Anonymous-Methods-Collection-Generiche.aspx</guid><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post1851/Anonymous-Methods-Collection-Generiche.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS1851.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=1851</trackback:ping></item><item><title>Generare documenti Office via ASP.NET</title><link>http://blogs.aspitalia.com/matteo/post1811/Generare-Documenti-Office-ASP.NET.aspx</link><pubDate>Tue, 31 Oct 2006 11:35:56 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=1811' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Quasi tutti noi abbiamo (almeno una volta, confessate!) avuto la necessità di creare nelle nostre applicazioni web funzionalità di esportazione dei dati in formato Exel o di generazione di documenti Word, trovandoci inevitabilmente a fare i conti con le difficoltà del caso (Office sul server? E chi ce l'ha???) &lt;/p&gt;&lt;p&gt;Il vecchio formato binario in uso da 10 anni in Office era infatti decisamente troppo complesso per essere manipolato fuori dalla suite di Microsoft (ok, le versioni 2000 e 2003 hanno introdotto la possibilità di creare documenti in formato XML ma è un po' un &amp;quot;optional&amp;quot; e con diverse limitazioni)&lt;/p&gt;&lt;p&gt;Però...&lt;/p&gt;&lt;p&gt;Se tra gli importanti e sostanziosi cambiamenti introdotti con &lt;strong&gt;Office 2007&lt;/strong&gt; quello più evidente è la nuova interfaccia grafica, quello più interessante è il cambiamento del &lt;strong&gt;formato dei documenti&lt;/strong&gt;: ora finalmente possiamo dire addio alle difficoltà di manipolazione dei documenti Office da codice e Ted Pattison, su MSDN Magazine di Novembre 2006 ci illustra quanto diventa semplice lavorare con Office usando .NET: &lt;a title="server-side generation of word 2007 docs" href="http://msdn.microsoft.com/msdnmag/issues/06/11/basicinstincts/default.aspx"&gt;Server-Side Generation of Word 2007 Docs&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Happy (office documents) programming!&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post1811/Generare-Documenti-Office-ASP.NET.aspx</guid><slash:comments>0</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post1811/Generare-Documenti-Office-ASP.NET.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS1811.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=1811</trackback:ping></item><item><title>Internet Explorer 7 - disponibile la RC1</title><link>http://blogs.aspitalia.com/matteo/post1717/Internet-Explorer-Disponibile-RC1.aspx</link><pubDate>Fri, 25 Aug 2006 08:07:00 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=1717' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;IE7 è finalmente giunto alla prima RC (Release Candidate), come annunciato sul &lt;a title="IEBlog" href="http://blogs.msdn.com/ie/default.aspx" target="_blank"&gt;blog del team&lt;/a&gt;: &lt;a title="IE7 RC1" href="http://blogs.msdn.com/ie/archive/2006/08/24/715752.aspx" target="_blank"&gt;Internet Explorer 7 Release Candidate Now Available&lt;/a&gt;. Nel post originale sono spiegate le variazioni.&lt;/p&gt;&lt;p&gt;La prima cosa che salta all'occhio sono le &lt;a title="Installation Changes in IE7 Release Candidate" href="http://blogs.msdn.com/ie/archive/2006/08/24/714977.aspx" target="_blank"&gt;Installation Changes in IE7 Release Candidate&lt;/a&gt; per cui non sarà più necessario rimuovere manualmente eventuali versioni precedenti (beh, ad ogni modo un paio di reboot non ve li toglie nessuno!)&lt;/p&gt;&lt;p&gt;Unico problema da me riscontrato: al termine dell'installazione non era più visibile la &amp;quot;Quick Start Toolbar&amp;quot; nella barra di Windows; niente di grave insomma :-)&lt;/p&gt;&lt;p&gt;Dimenticavo il link diretto per il download (gratuito, previa autenticazione della copia di Windows) di &lt;a title="Download IE7 RC1" href="http://www.microsoft.com/ie/" target="_blank"&gt;IE7 RC1&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;Enjoy!&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post1717/Internet-Explorer-Disponibile-RC1.aspx</guid><slash:comments>3</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post1717/Internet-Explorer-Disponibile-RC1.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS1717.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=1717</trackback:ping></item><item><title>Quanti motivi ci sono per passare a Visual Studio 2005?</title><link>http://blogs.aspitalia.com/matteo/post1529/Motivi-Passare-Visual-Studio-2005.aspx</link><pubDate>Thu, 23 Mar 2006 10:41:00 GMT</pubDate><description>&lt;img src='http://blogs.aspitalia.com/services/counter_rss.aspx?PostID=1529' border="0" style="width:1px; height:1px;" /&gt;&lt;p&gt;Più di 400.&lt;/p&gt;&lt;p&gt;Non ci credete? &lt;br /&gt;Allora guardate qua: &lt;a href="http://www.400plusdifferences.com/"&gt;http://www.400plusdifferences.com/&lt;/a&gt;&lt;/p&gt;&lt;hr /&gt;&lt;p&gt;&lt;a href="http://www.aspitalia.com/"&gt;(C) 2008 ASPItalia.com Network - All rights reserved&lt;/a&gt;&lt;/p&gt;</description><dc:creator>Matteo Casati</dc:creator><category>.NET</category><guid isPermaLink="true">http://blogs.aspitalia.com/matteo/post1529/Motivi-Passare-Visual-Studio-2005.aspx</guid><slash:comments>3</slash:comments><wfw:comments>http://blogs.aspitalia.com/matteo/post1529/Motivi-Passare-Visual-Studio-2005.aspx#feedback</wfw:comments><wfw:commentRss>http://blogs.aspitalia.com/matteo/CommentRSS1529.aspx</wfw:commentRss><trackback:ping>http://blogs.aspitalia.com/services/trackback.aspx?PostID=1529</trackback:ping></item></channel></rss>