<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Massimiliano Spinetti PMP</title>
	<atom:link href="http://www.massimilianospinettipmp.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.massimilianospinettipmp.info</link>
	<description>I bravi programmatori sanno cosa scrivere, i migliori sanno cosa riscrivere e riusare. (Eric Steven Raymond)</description>
	<lastBuildDate>Mon, 04 Apr 2011 07:41:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Extension method</title>
		<link>http://www.massimilianospinettipmp.info/2010/12/extension-method/</link>
		<comments>http://www.massimilianospinettipmp.info/2010/12/extension-method/#comments</comments>
		<pubDate>Wed, 01 Dec 2010 14:38:49 +0000</pubDate>
		<dc:creator>Massimiliano Spinetti</dc:creator>
				<category><![CDATA[Framework .NET]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[ereditarietà]]></category>
		<category><![CDATA[Extension]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Ienumerable]]></category>
		<category><![CDATA[intellisense]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Linkq]]></category>
		<category><![CDATA[Method]]></category>
		<category><![CDATA[Object]]></category>
		<category><![CDATA[sealed]]></category>

		<guid isPermaLink="false">http://www.massimilianospinettipmp.info/?p=305</guid>
		<description><![CDATA[In questo breve post voglio parlare degli Extension Method, una novità introdotta con la versione 3 del Framework. Difficoltà: Piattaforma: C#. Il loro principale utilizzo è quello di estendere i metodi di una classe quando non è possibile utilizzare l&#8217;ereditarietà, quando non si ha il codice sorgente o quando semplicemente, si vogliono aggiungere metodi senza [...]]]></description>
			<content:encoded><![CDATA[<p><em>In questo breve post voglio parlare degli Extension Method, una novità introdotta con la versione 3 del Framework.</em></p>
<p><strong>Difficoltà</strong>:<a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/11/Valutazione-semplice3.png"><img title="Valutazione semplice" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/11/Valutazione-semplice3.png" alt="" width="96" height="24" /></a><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/Valutazione-semplice.png"></a><br />
<strong>Piattaforma:</strong> <span style="color: #008000;">C#. </span></p>
<p style="text-align: justify;">Il loro principale utilizzo è quello di <strong>estendere i metodi</strong> di una classe quando non è possibile utilizzare <strong>l&#8217;ereditarietà</strong>, quando non si ha il <strong>codice sorgente</strong> o quando semplicemente, si vogliono aggiungere metodi senza dover modificare la classe originale.<br />
Gli <a title="Extension method msn" href="http://msdn.microsoft.com/en-us/library/bb383977.aspx"><strong>Extension method</strong></a> vengono dichiarati come <strong>metodi statici</strong> di classi esterne statiche, e vengono riconosciuti <strong>dall&#8217;Intellisense</strong> come metodi interni alla classe.</p>
<p style="text-align: justify;">In <strong>C#</strong> la dichiarazione di un <strong>Extended Method</strong> è quindi simile a quella di un <strong>metodo statico</strong>, fatta eccezione per il primo parametro del metodo che è composto dalla parola chiave <strong>this</strong> e dal <strong>nome del tipo</strong> da estendere.</p>
<p>Sebbene a prima vista la differenza che c&#8217;è tra un<strong> Extension method</strong> ed un normale metodo di classe sembra molto poca, in realtà gli utilizzi che se ne possono fare sono diversi, basti pensare ad esempio che gli Extension method vengono usati dalla classe <strong>Enumerable</strong> di  <strong>Linq</strong> per estendere l&#8217;interfaccia generica <strong>IEnumerable</strong> </p>
<p style="text-align: justify;">Pur essendo dei metodi statici di classe, questi appaiono come <strong>metodi dell&#8217;istanza</strong> ma non possono però accedere alle variabili private interne all&#8217;istanza.<br />
Inoltre, al contrario <strong>dell&#8217;ereditarietà</strong> in cui è possibile fare <strong>l&#8217;ovverride</strong> di un metodo della classe <strong>parent</strong>, nel caso degli extension method, se la classe base e la classe che estende hanno un metodo con <strong>stessa firma</strong>, allora verrà eseguito automaticamente il metodo della classe base. E&#8217; invece consentito <strong>l&#8217;overload</strong>.  </p>
<p style="text-align: justify;">Vediamo ora un esempio e creiamo la classe da estendere <strong>UserClass</strong>:</p>
<p><span style="font-family: courier new,courier;">    public class UserClass<br />
    {<br />
        private string m_Name;<br />
        private string m_Surname;<br />
        private Int16 m_Age;</span></p>
<p><span style="font-family: courier new,courier;">        public UserClass()<br />
        {<br />
            this.m_Name = &#8220;&#8221;;<br />
            this.m_Surname = &#8220;&#8221;;<br />
            this.m_Age = 10;<br />
        }<br />
        public string Name<br />
        {<br />
            get<br />
            {<br />
                return m_Name;<br />
            }<br />
            set<br />
            {<br />
                m_Name = value;<br />
            }<br />
        }</span></p>
<p><span style="font-family: courier new,courier;">        public string Surname<br />
        {<br />
            get<br />
            {<br />
                return m_Surname;<br />
            }<br />
            set<br />
            {<br />
                m_Surname = value;<br />
            }<br />
        }</span></p>
<p><span style="font-family: courier new,courier;">        public Int16 Age<br />
        {<br />
            get<br />
            {<br />
                return m_Age;<br />
            }<br />
            set<br />
            {<br />
                m_Age = value;<br />
            }<br />
        }</span></p>
<p style="text-align: justify;">Ora creiamo la classe <strong>UserClassExtension</strong> che estenderà la prima:</p>
<p style="text-align: justify;"><span style="font-family: courier new,courier;">    public static class<span style="color: #ff6600;"> UserClassExtension</span><br />
    {<br />
        public static Boolean <span style="color: #ff6600;">IsAdult(this UserClass user)</span><br />
        {<br />
            if (user.Age &gt;= 18)<br />
            {<br />
                return true;<br />
            }<br />
            else<br />
            {<br />
                return false;<br />
            }<br />
        }<br />
    }</span></p>
<p style="text-align: justify;">Qui è visibile l&#8217;unico metodo <strong>IsAdult</strong> che vuole come <strong>unico parametro</strong> un istanza del tipo da estendere.</p>
<p style="text-align: justify;">A questo punto possiamo andare ad istanziare un oggetto del tipo <strong>UserClass</strong> e possiamo vedere: sia come <strong>l&#8217;intellisense</strong> riconosce il metodo come se fosse effettiva parte integrante della classe, sia come il metodo statico venga effettivamente eseguito sull&#8217;istanza corrente.</p>
<p style="text-align: justify;"><span style="font-family: courier new,courier;">            UserClass User = new UserClass();<br />
            User.Name = &#8220;Jon&#8221;;<br />
            User.Surname = &#8220;Doe&#8221;;<br />
            User.Age = 18;<br />
             <br />
            if <span style="color: #ff6600;">(User.IsAdult())</span><br />
            {MessageBox.Show(&#8220;Adult&#8221;);}<br />
            else<br />
            { MessageBox.Show(&#8220;Child&#8221;); }</span></p>
<p style="text-align: justify;">Possiamo notare inoltre che il metodo non richiede nessun parametro in ingresso, infatti il primo parametro che è quello che identifica l&#8217;istanza, viene omesso.</p>
<p style="text-align: justify;">Per testare come si comporta un <strong>Extension Method</strong> nel caso in cui il metodo esista già, facciamo un altro esempio.</p>
<p style="text-align: justify;">Creiamo una classe <strong>Sealed UserFinalClass </strong>che ha già un metodo <strong>IsAdult</strong></p>
<p><span style="font-family: courier new,courier;">   public sealed class UserFinalClass<br />
    {<br />
        private string m_Name;<br />
        private string m_Surname;<br />
        private Int16 m_Age;</span></p>
<p><span style="font-family: courier new,courier;">        public UserFinalClass()<br />
        {<br />
            this.m_Name = &#8220;&#8221;;<br />
            this.m_Surname = &#8220;&#8221;;<br />
            this.m_Age = 9;<br />
        }<br />
     <br />
     &#8230;<br />
     &#8230;<br />
     <br />
        <span style="color: #ff6600;">public bool IsAdult()</span><br />
        {<br />
            if (this.m_Age &gt;= 18)<br />
            {<br />
                return true;<br />
            }<br />
            else<br />
            {<br />
                return false;<br />
            }<br />
        }<br />
    }</span></p>
<p style="text-align: justify;"> Creaiamo ora la classe che la estenderà:</p>
<p><span style="font-family: courier new,courier;">  public static class UserFinalClassExtension<br />
    {<br />
        public static Boolean <span style="color: #ff6600;">IsAdult(this UserFinalClass user)<br />
</span>        {<br />
            if (user.Age &gt;= 16)<br />
            {<br />
                return true;<br />
            }<br />
            else<br />
            {<br />
                return false;<br />
            }<br />
        }</span></p>
<p><span style="font-family: courier new,courier;">        public static Boolean <span style="color: #ff6600;">IsTeenAger(this UserFinalClass user)<br />
</span>        {<br />
            if ((user.Age &gt;= 13) &amp;&amp; (user.Age &lt;= 19))<br />
            {<br />
                return true;<br />
            }<br />
            else<br />
            {<br />
                return false;<br />
            }<br />
        }</span></p>
<p><span style="font-family: courier new,courier;">    }</span></p>
<p style="text-align: justify;">In questo caso,  eseguendo il codice seguente, possiamo notare che per metodo <strong>IsAdult</strong> verrà chiamato quello definito nella classe base mentre per il metodo <strong>IsTeenAger</strong> verrà chiamato <strong>l&#8217;Extension method.</strong></p>
<p><span style="font-family: courier new,courier;">   </span><span style="font-family: courier new,courier;">         UserFinalClass UserFinal = new UserFinalClass();<br />
            UserFinal.Name = &#8220;Jon&#8221;;<br />
            UserFinal.Surname = &#8220;Doe&#8221;;<br />
            UserFinal.Age = 16;</span></p>
<p><span style="font-family: courier new,courier;">            if <span style="color: #ff6600;">(UserFinal.IsAdult())</span><br />
            { MessageBox.Show(&#8220;Adult&#8221;); }<br />
            else<br />
            { MessageBox.Show(&#8220;Child&#8221;); }</span></p>
<p><span style="font-family: courier new,courier;">            if <span style="color: #ff6600;">(UserFinal.IsTeenAger())</span><br />
            { MessageBox.Show(&#8220;Teenager&#8221;); }<br />
            else<br />
            { MessageBox.Show(&#8220;I&#8217;m not a teenager&#8221;); }</span></p>
<p>In conclusione, abbiamo visto come usando gli <strong>Extension method</strong> è possibile  crearsi librerie esterne che estendono classi esistenti, ad esembio le classi basi del framework. Potete trovare qualche metodo utile su questo <a title="Extension Method example" href="http://www.extensionmethod.net">link</a>.</p>
<p>Alla prossima</p>
]]></content:encoded>
			<wfw:commentRss>http://www.massimilianospinettipmp.info/2010/12/extension-method/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ottimizziamo il codice con tre semplici pattern</title>
		<link>http://www.massimilianospinettipmp.info/2010/11/tre-piccoli-pattern/</link>
		<comments>http://www.massimilianospinettipmp.info/2010/11/tre-piccoli-pattern/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 23:31:21 +0000</pubDate>
		<dc:creator>Massimiliano Spinetti</dc:creator>
				<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Creazionale]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[IsDirty]]></category>
		<category><![CDATA[Lazy]]></category>
		<category><![CDATA[load balancing]]></category>
		<category><![CDATA[Object]]></category>
		<category><![CDATA[Pattern]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://www.massimilianospinettipmp.info/?p=291</guid>
		<description><![CDATA[In questo post ho deciso di parlare di tre semplici design patterns, tutti  per lo più orientati all’ottimizzazione nell’esecuzione di operazioni /processi onerosi Difficoltà: Piattaforma: VB.NET Come prima cosa definiamo brevemente  che cos’è un Design pattern. Un Pattern è un modello o un schema,  e  in campo informatico,  in particolare nella programmazione Object Oriented, si parla [...]]]></description>
			<content:encoded><![CDATA[<p><em>In questo post ho deciso di parlare di tre semplici design patterns, tutti  per lo più orientati all’ottimizzazione nell’esecuzione di operazioni /processi onerosi</em></p>
<p><strong>Difficoltà</strong>:<a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/11/Valutazione-semplice3.png"><img title="Valutazione semplice" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/11/Valutazione-semplice3.png" alt="" width="96" height="24" /></a><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/Valutazione-semplice.png"></a><br />
<strong>Piattaforma:</strong> <span style="color: #008000;">VB.NET </span></p>
<p style="text-align: justify;">Come prima cosa definiamo brevemente  che cos’è un <a href="http://it.wikipedia.org/wiki/Design_pattern"><strong>Design pattern</strong></a><strong>.</strong></p>
<p style="text-align: justify;">Un<strong> </strong><a href="http://it.wikipedia.org/wiki/Pattern"><strong>Pattern</strong></a> è un modello o un schema,  e  in campo informatico,  in particolare <strong>nella </strong><a href="http://it.wikipedia.org/wiki/Programmazione_orientata_agli_oggetti"><strong>programmazione Object Oriented</strong></a>, si parla di Design pattern,  per descrivere <strong>soluzioni progettuali  generalizzate</strong> applicabili a determinati  tipi di problemi ricorrenti o che si possono verificare in diverse situazioni.</p>
<p style="text-align: justify;">Un <strong>design pattern</strong> è quindi caratterizzato da: un <strong>nome</strong> che generalmente ne richiama il comportamento, da una <strong>descrizione</strong> di un <strong>problema o contesto</strong> generico cui può essere applicato  e da una <strong>descrizione</strong> generalizzata della <strong>soluzione </strong>che verrà applicata.</p>
<p style="text-align: justify;">In futuro su questo blog approfondirò di più l’argomento.</p>
<h4><span style="color: #006699;">Lazy Inizialization</span></h4>
<p>Questo pattern è utilizzato principalmente quando è necessario effettuare operazioni di lettura dati particolarmente  <strong>time consuming</strong> o impegnative.  Un esempio potrebbe essere la lettura di dati di inizializzazione da un database.<br />
Queste verranno eseguite solo quando <strong>effettivamente sono necessarie</strong> e da qui ne deriva il nome  <strong>“Inizializzazione Pigra”</strong></p>
<p style="text-align: justify;">Come dicevo l’implementazione è estremamente semplice e prevede l’utilizzo di un <strong>flag</strong> interno usato per tracciare se i dati sono già stati effettivamente caricati.</p>
<p><span style="font-family: courier new,courier;">Public Class LazyInitializerClass<br />
    <span style="color: #ff6600;">Private m_DataInizialized As Boolean</span><br />
    Private m_DataToRead As String<br />
    Public Sub New()<br />
        m_DataInizialized = False<br />
        &#8216; reset Data<br />
        m_DataToRead = &#8220;&#8221;<br />
    End Sub<br />
    Public ReadOnly Property MyData() As String<br />
        Get<br />
            <span style="color: #ff6600;">If Not m_DataInizialized Then Initialize()</span><br />
            Return m_DataToRead<br />
        End Get<br />
    End Property<br />
<span style="color: #ff6600;">    Private Sub Initialize()<br />
        m_DataInizialized = True<br />
        &#8216; read Data<br />
        m_DataToRead = &#8220;Data From Database&#8221;<br />
    End Sub</span><br />
    Public Sub Refresh()<br />
        m_DataInizialized = False<br />
    End Sub<br />
End Class</span></p>
<p style="text-align: justify;">Inizialmente, quando <strong>l’oggetto viene creato</strong>, il flag viene <strong>impostato a false</strong>. Successivamente quando la property viene chiamata per la prima volta, i dati vengono letti ed il flag di controllo viene impostato a true.<br />
Tutte <strong>le interrogazioni successive</strong> della property  invece,  non leggeranno più la sorgente dei dati, ma ne restituiranno direttamente il contenuto precedentemente letto.</p>
<p style="text-align: justify;">In questo esempio ho aggiunto  il metodo di <strong>refresh</strong> che ci permetta di ricaricare i dati dal DB.</p>
<h4><span style="color: #006699;">Pattern IsDirty</span></h4>
<p style="text-align: justify;">Questo pattern è di natura simile  al precedente, ed è principalmente utilizzato per <strong>ottimizzare  operazioni di salvataggio</strong> di un determinato oggetto, ovvero queste ultime verranno eseguite <strong>solo quando</strong> sono state fatte effettivamente delle modifiche all&#8217;oggetto.<br />
Anche qui il principio è molto semplice e si basa sull’utilizzo di un <strong>flag interno</strong> che viene impostato a true tutte le volte che una <strong>property cambia</strong>.</p>
<p style="text-align: justify;"><span style="font-family: courier new,courier;">Public Class IsDirtyClass<br />
    <span style="color: #ff6600;">Private m_IsDirty As Boolean</span><br />
    Private m_MyData As String<br />
    Public Property MyData() As String<br />
        Get<br />
            Return m_MyData<br />
        End Get<br />
        Set(ByVal value As String)<br />
            <span style="color: #ff6600;">m_IsDirty = True</span><br />
            m_MyData = value<br />
        End Set<br />
    End Property<br />
    Public Sub New()<br />
        m_IsDirty = False<br />
        &#8216; reset Data<br />
        m_MyData = &#8220;&#8221;<br />
    End Sub<br />
<span style="color: #ff6600;">    Public Sub Save()<br />
        If m_IsDirty Then<br />
            &#8216; Save Data<br />
            m_IsDirty = False<br />
        End If<br />
    End Sub</span><br />
end Class</span></p>
<p style="text-align: justify;">Il metodo che effettua il salvataggio <strong>verificherà</strong> quindi che almeno una <strong>property è cambiata, </strong> in caso contrario non effettuerà nessuna operazione l’inutile .</p>
<h4><span style="color: #006699;">Singleton</span></h4>
<p style="text-align: justify;">Questo pattern si discosta leggermente dai primi due poiché, sebbene utilizzi un principio di <strong>Lazy iniziatialization</strong>, la sua caratteristica principale è quella di assicurarsi che <strong>esita una sola istanza attiva</strong> di una data classe.<br />
E’ un pattern molto usato a volte eccessivamente  o impropriamente  applicato e da qui anche la fama, a mio avviso ingiustificata,  di essere anche un <strong>anti pattern</strong>. Sebbene molto semplice nell’implementazione vale la pena spendere due parole in più.<br />
<strong>Singleton</strong> è un cosi detto pattern <strong>creazionale</strong>, ovvero fa parte della famiglia di quei patterns  che,  modificando l’approccio standard alla  creazione delle proprie istanze, (in questo caso rendendo privato il costruttore),  nascondono al client le modalità in cui vengono create le istanze stesse.</p>
<p>I <strong>real case</strong>  dove più è utilizzato sono i casi in cui è necessario <strong>centralizzare il controllo</strong> di uno o più processi su singolo oggetto,  dove è necessario<strong> fornire un unico punto di accesso</strong> condiviso a determinate risorse o infine, in contesti di<strong> load balancing</strong>.</p>
<p>Il principio di funzionamento è molto semplice, l’istanza viene creata la prima volta che si accede alla variabile  e non all’avvio del programma.<br />
Tutte le volte che viene richiesta una nuova istanza, viene fornito il riferimento all’istanza esistente.</p>
<p>Per far questo viene dichiarato nella classe un oggetto interno privato dello stesso tipo della classe<br />
Viene poi <strong>mascherato  il costruttore</strong> mentre la creazione della prima istanza o la <strong>restituzione del riferimento all’istanza</strong> esistente viene fatta attraverso un <strong>metodo statico</strong>.</p>
<p><span style="font-family: courier new,courier;"> Public Class SingleTonClass<br />
    <span style="color: #ff9900;">Private Shared m_instance As SingleTonClass<br />
</span>    Protected Sub New()<br />
    End Sub<br />
    Public Shared Function GetInstance() As SingleTonClass<br />
<span style="color: #ff9900;">        If m_instance Is Nothing Then<br />
            m_instance = New SingleTonClass<br />
        End If</span><br />
        Return m_instance<br />
    End Function<br />
End Class</span></p>
<p>E’ importante ricordare che nel caso ci siano <strong>più client o thread</strong> che istanziano questa classe,  è necessario, anche se il framework .NET ci viene già incontro,  governarne <strong>l’accesso concorrente</strong> ai dati con dei <strong>lock</strong>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.massimilianospinettipmp.info/2010/11/tre-piccoli-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rendiamo i nostri oggetti ordinabili</title>
		<link>http://www.massimilianospinettipmp.info/2010/10/rendiamo-i-nostri-oggetti-ordinabili/</link>
		<comments>http://www.massimilianospinettipmp.info/2010/10/rendiamo-i-nostri-oggetti-ordinabili/#comments</comments>
		<pubDate>Mon, 25 Oct 2010 13:40:49 +0000</pubDate>
		<dc:creator>Massimiliano Spinetti</dc:creator>
				<category><![CDATA[Framework .NET]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Compare]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Interface]]></category>
		<category><![CDATA[Object]]></category>
		<category><![CDATA[Ordinamento]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://www.massimilianospinettipmp.info/?p=274</guid>
		<description><![CDATA[Come rendere confrontabili i nostri oggetti.  Ordiniamo un ArrayList implementando le giuste interfacce. Difficoltà: Piattaforma: VB.NET  Se stiamo lavorando con tipi di dati valore,  è possibile effettuare paragoni attraverso l’utilizzo dei classici operatori di confronto  maggiore (&#62;), minore (&#60;)  = e uguale (=). Anche per i tipi stringa è possibile usare tali operatori, anche se in [...]]]></description>
			<content:encoded><![CDATA[<p><em>Come rendere confrontabili i nostri oggetti. <br />
Ordiniamo un ArrayList implementando le giuste interfacce.</em></p>
<p><strong>Difficoltà</strong>:<a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/Valutazione-medio.png"><img title="Difficoltà media" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/Valutazione-medio.png" alt="" width="96" height="24" /></a><br />
<strong>Piattaforma:</strong> <span style="color: #008000;">VB.NET </span></p>
<p style="text-align: justify;">Se stiamo lavorando con tipi di dati valore,  è possibile effettuare paragoni attraverso l’utilizzo dei classici operatori di confronto  <strong><em>maggiore</em></strong> (&gt;), <strong><em>minore</em></strong> (&lt;)  = e <strong><em>uguale</em></strong> (=).<br />
Anche per i tipi <strong>stringa</strong> è possibile usare tali operatori, anche se in questo caso , l’ordinamento può essere condizionato da opzioni di “<strong>Option Compare</strong>”  o  dalle <strong>impostazioni internazionali</strong>.</p>
<p style="text-align: justify;">Ma cosa succede se abbiamo bisogno di confrontare degli oggetti?<br />
Il <strong>Framework</strong> <strong>.NET</strong> ci mette a disposizione <strong>l’interfaccia</strong> <strong>IComparable</strong>. Attraverso l’implementazione di questa interfaccia, e più precisamente dell&#8217; unico metodo <strong>compareTo(Object)</strong> è possibile comunicare al metodo chiamante,  se il nostro oggetto è maggiore o meno rispetto ad un secondo oggetto passato come parametro.</p>
<p style="text-align: justify;">Mentre i <strong>valori numerici</strong>, le <strong>stringhe</strong> e le <strong>date</strong> hanno già il metodo <strong>CompareTo</strong>, per le nostre <strong>classi</strong>  è necessario implementarla <strong>manualmente</strong>. <br />
Verificandone l’implementazione negli oggetti contentuti, classi come <strong>Arraylist</strong> sono in grado, chiamando automaticamente il metodo <strong>CompareTo</strong>,  di restituire elenchi ordinati.</p>
<p style="text-align: justify;">Possiamo verificarlo creando ad esempio una <strong>lista di stringhe</strong> e chiamando successivamente il metodo <strong>Sort </strong>di un ArrayList.</p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">Dim Product1 As String<br />
Dim Product2 As String<br />
Dim Product3 As String<br />
Dim Product4 As String</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">Dim sSortedObject As String = &#8220;&#8221;</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">Try<br />
    Product1 = &#8220;Parallelepiped 1&#8243;<br />
    Product2 = &#8220;Parallelepiped 2&#8243;<br />
    Product3 = &#8220;Parallelepiped 3&#8243;<br />
    Product4 = &#8220;Parallelepiped 4&#8243;</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Dim myList As New ArrayList</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    myList.Add(Product4)<br />
    myList.Add(Product1)<br />
    myList.Add(Product2)<br />
    myList.Add(Product3)</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    <span style="color: #ff6600;">myList.Sort()</span></span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    For Each obj In myList<br />
        sSortedObject &amp;= obj &amp; vbCrLf<br />
    Next</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    MessageBox.Show(sSortedObject)<br />
Catch ex As Exception<br />
    MessageBox.Show(ex.Message)<br />
End Try</span></p>
<p style="text-align: justify;"><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/01_String.png"></a></p>
<p style="text-align: justify;"><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/01_String1.png"><img class="aligncenter size-full wp-image-280" title="01_String" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/01_String1.png" alt="" width="164" height="215" /></a></p>
<p style="text-align: justify;">Nel caso in cui il nostro <strong>Arraylist</strong> contenga un elenco di<strong> oggetti non confrontabili</strong>, il metodo <strong>Sort</strong> ci restituisce un errore.</p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">Dim Product1 As ProductClass                               <br />
Dim Product2 As ProductClass                               <br />
Dim Product3 As ProductClass                               <br />
Dim Product4 As ProductClass                               <br />
                                                           <br />
Dim sSortedObject As String = &#8220;&#8221;                           <br />
                                                           <br />
Try                                                        <br />
    Product1 = New ProductClass(5, 5, 5, &#8220;Parallelepiped 1&#8243;)<br />
    Product2 = New ProductClass(6, 6, 6, &#8220;Parallelepiped 2&#8243;)<br />
    Product3 = New ProductClass(3, 4, 5, &#8220;Parallelepiped 3&#8243;)<br />
    Product4 = New ProductClass(6, 6, 2, &#8220;Parallelepiped 4&#8243;)<br />
                                                        <br />
    Dim myList As New ArrayList                             <br />
                                                        <br />
    myList.Add(Product1)                                    <br />
    myList.Add(Product2)                                    <br />
    myList.Add(Product3)                                    <br />
    myList.Add(Product4)                                  <br />
                                                        <br />
  <span style="color: #ff6600;">  myList.Sort()</span>                                           <br />
                                                        <br />
    For Each obj In myList                                  <br />
        sSortedObject &amp;= obj.Name &amp; vbCrLf                  <br />
    Next                                                    <br />
                                                        <br />
    MessageBox.Show(sSortedObject)                         <br />
Catch ex As Exception                                       <br />
    MessageBox.Show(ex.Message &amp; ex.InnerException.Message)<br />
End Try </span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;"><em>(Non ho implemento qui la classe ProductClass per motivi di praticità, in ogni caso verrà rivista più avanti.)</em></span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;"><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/02_Object.png"><img class="aligncenter size-full wp-image-278" title="02_Object" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/02_Object.png" alt="" width="476" height="170" /></a></span></p>
<h4><span style="color: #006699;">Implementare il metodo CompareTo</span></h4>
<p style="text-align: justify;">Questo metodo prevede la <strong>restituzione</strong> di un valore <strong>minore di zero</strong> nel caso in cui l’oggetto è più piccolo di quello passato come parametro, di <strong>zero</strong> nel caso in cui siano uguali e <strong>maggiore di zero</strong> nel caso in cui sia più grande.</p>
<p style="text-align: justify;">Creiamo una classe che implementa l’interfaccia <strong>IComparable</strong></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">Public Class ProductClassComparable<br />
    <span style="color: #ff6600;">Implements IComparable</span></span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Private m_height As Integer<br />
    Private m_width As Integer<br />
    Private m_length As Integer</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Private m_Name As String</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Public Sub New()<br />
        m_height = 0<br />
        m_width = 0<br />
        m_length = 0<br />
    End Sub<br />
    Public Sub New(ByVal iHeight As Integer, ByVal iWidth As Integer, ByVal iLength As Integer, ByVal sName As String)<br />
        m_height = iHeight<br />
        m_width = iWidth<br />
        m_length = iLength<br />
        m_Name = sName<br />
    End Sub</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Public Property Height() As Integer<br />
        Get<br />
            Return m_height<br />
        End Get<br />
        Set(ByVal value As Integer)<br />
            m_height = value<br />
        End Set<br />
    End Property<br />
    Public Property Width() As Integer<br />
        Get<br />
            Return m_width<br />
        End Get<br />
        Set(ByVal value As Integer)<br />
            m_width = value<br />
        End Set<br />
    End Property</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Public Property Length() As Integer<br />
        Get<br />
            Return m_length<br />
        End Get<br />
        Set(ByVal value As Integer)<br />
            m_length = value<br />
        End Set<br />
    End Property</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Public Property Name() As String<br />
        Get<br />
            Return m_Name<br />
        End Get<br />
        Set(ByVal value As String)<br />
            m_Name = value<br />
        End Set<br />
    End Property</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">    Public ReadOnly Property GetVolume() As Decimal<br />
        Get<br />
            Return (m_height * m_length * m_width)<br />
        End Get<br />
    End Property</span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;"><span style="color: #ff9900;"> <span style="color: #ff6600;">   Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo<br />
        If Me.Name &lt; obj.Name Then<br />
            Return -1<br />
        ElseIf Me.Name &gt; obj.Name Then<br />
            Return 1<br />
        Else<br />
            Return 0<br />
        End If<br />
    End Function</span></span></span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">End Class</span></p>
<p style="text-align: justify;">Il metodo principale qui è <strong>CompareTo(Object)</strong> dove viene effettuato il confronto vero e proprio e viene restituito il risultato.<br />
E’ importante notare che all’interno di questo metodo possiamo implementare il tipo di controllo che ci serve, ad esempio un operazione, il confronto sul numero di caratteri etc, <strong>ma un vincolo di questa soluzione</strong> è il fatto che stiamo definendo <strong>una regola precisa di confronto</strong> tra oggetti, e quindi, nel caso di qualsiasi futuro ordinamento, siamo <strong>vincolati a questa regola</strong>.<br />
Dato inoltre che non stiamo lavorando con un ArrayList di <strong>generici</strong>, è inoltre consigliato aggiungere gli opportuni controlli sul tipo di oggetto passato come parametro. </p>
<h4 style="text-align: justify;"><span style="color: #006699;">Ordinare utilizzando un oggetto IComparer</span></h4>
<p style="text-align: justify;">Una <strong>soluzione alternativa</strong> è quella di andare a creare una classe che implementi l’interfaccia <strong>IComparer</strong> e che si occupi di effettuare il confronto tra i due oggetti. Un&#8217;istanza di questa classe verrà passata come parametro al metodo <strong>Sort</strong> dell&#8217;<strong>ArrayList.</strong></p>
<p style="text-align: justify;">Analogamente al metodo <strong>CompareTo</strong>, anche il metodo <strong>Compare</strong> restituisce in <strong>Int32</strong> che dice al chiamante se il primo oggetto è maggiore o minore del secondo oggetto.</p>
<p style="text-align: left;"><span style="font-family: courier new,courier;">Public Class ComparerProductClass<br />
    <span style="color: #ff6600;">Implements IComparer</span><br />
    Public Sub New()<br />
        MyBase.New()<br />
    End Sub<br />
    <span style="color: #ff6600;">Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements        System.Collections.IComparer.Compare</span></span></p>
<p style="text-align: left;"><span style="font-family: courier new,courier;"><span style="color: #ff6600;"><span style="color: #008000;">     &#8216; &#8230; Implementazione del codice di confronto tra gli oggetti</span></span></span><span style="font-family: courier new,courier;"><span style="color: #ff6600;"><br />
    End Function</span><br />
End Class</span></p>
<h4><span style="color: #006699;">Generalizzare il nostro oggetto Comparer</span></h4>
<p style="text-align: justify;">Con un po’ di <strong>reflection</strong> e un paio di <strong>property</strong> in più possiamo costruire una <strong>classe comparer</strong> che ci permetta di generalizzare il nome della <strong>property</strong> su cui effettuare il confronto oltre al <strong>verso dell&#8217;ordinamento</strong>.</p>
<p><span style="font-family: courier new,courier;"><span style="color: #ff6600;">Imports System.Reflection</span><br />
Public Class ComparerGeneralizedClass<br />
    <span style="color: #ff6600;">Implements IComparer</span></span></p>
<p><span style="font-family: courier new,courier;">    Private m_propertyname As String<br />
    Private m_ascending As Boolean</span></p>
<p><span style="font-family: courier new,courier;">    &#8216; Costruttore<br />
    Public Sub New(ByVal PropertyName As String, ByVal Ascending As Boolean)<br />
        m_propertyname = PropertyName<br />
        m_ascending = Ascending<br />
    End Sub</span></p>
<p><span style="font-family: courier new,courier;">    <span style="color: #ff6600;">Public Function Compare(ByVal obj1 As Object, ByVal obj2 As Object) As Integer Implements System.Collections.IComparer.Compare</span><br />
        Dim iResult As Integer</span></p>
<p><span style="font-family: courier new,courier;">        Dim Type_obj1 As Type<br />
        Dim Type_obj2 As Type</span></p>
<p><span style="font-family: courier new,courier;">        Dim PropertyInfo_obj1 As PropertyInfo<br />
        Dim PropertyInfo_obj2 As PropertyInfo</span></p>
<p><span style="font-family: courier new,courier;">        Dim Valueobj1 As IComparable<br />
        Dim Valueobj2 As IComparable</span></p>
<p><span style="font-family: courier new,courier;">        Type_obj1 = obj1.GetType()<br />
        Type_obj2 = obj2.GetType()</span></p>
<p><span style="font-family: courier new,courier;">        &#8216; Verificare che la Property Esista<br />
        PropertyInfo_obj1 = Type_obj1.GetProperty(m_propertyname)<br />
        PropertyInfo_obj2 = Type_obj2.GetProperty(m_propertyname)</span></p>
<p><span style="font-family: courier new,courier;">        If PropertyInfo_obj1 Is Nothing Then<br />
            &#8216; Property  non Esiste<br />
            Throw New Exception(&#8220;Property &#8221; &amp; m_propertyname &amp; &#8221; doesn&#8217;t Exist&#8221;)<br />
        End If<br />
        If PropertyInfo_obj2 Is Nothing Then<br />
            &#8216; Property  non Esiste<br />
            Throw New Exception(&#8220;Property &#8221; &amp; m_propertyname &amp; &#8221; doesn&#8217;t Exist&#8221;)<br />
        End If</span></p>
<p><span style="font-family: courier new,courier;">        Valueobj1 = PropertyInfo_obj1.GetValue(obj1, Nothing)<br />
        Valueobj2 = PropertyInfo_obj2.GetValue(obj2, Nothing)</span></p>
<p><span style="font-family: courier new,courier;">        If Valueobj1 Is Nothing Then<br />
            &#8216; Property  non IComparable<br />
            Throw New Exception(&#8220;Property &#8221; &amp; m_propertyname &amp; &#8221; is not IComparable&#8221;)<br />
        End If<br />
        If Valueobj2 Is Nothing Then<br />
            &#8216; Property  non IComparable<br />
            Throw New Exception(&#8220;Property &#8221; &amp; m_propertyname &amp; &#8221; is not IComparable&#8221;)<br />
        End If</span></p>
<p><span style="font-family: courier new,courier;">        iResult = Valueobj1.CompareTo(Valueobj2)</span></p>
<p><span style="font-family: courier new,courier;">        If iResult &lt;&gt; 0 Then<br />
            If m_ascending Then<br />
                Return iResult<br />
            Else<br />
                Return (-iResult)<br />
            End If<br />
        End If</span></p>
<p><span style="font-family: courier new,courier;">        Return 0<br />
    End Function<br />
End Class</span></p>
<p style="text-align: justify;">Vediamone a questo punto il codice.<br />
Come prima cosa abbiamo aggiunto due <strong>property</strong>, la prima di tipo <strong>String</strong>, dove andiamo ad inserire il<strong> nome della property</strong> su cui vogliamo effettuare l&#8217;ordinamento, mentre la seconda di tipo <strong>Boolean</strong>, ci serve per capire se vogliamo fare un ordinamento dal più piccolo al più grande o viceversa.<br />
Nel <strong>costruttore</strong> obblighiamo l&#8217;inserimento di questi due parametri</p>
<p><span style="font-family: courier new,courier;">Public Sub New(ByVal PropertyName As String, ByVal Ascending As Boolean)</span></p>
<p>Nel metodo <strong>Compare</strong> invece, come prima cosa andiamo a recuperare il tipo degli oggetti</p>
<p><span style="font-family: courier new,courier;">Type_obj1 = obj1.GetType()<br />
Type_obj2 = obj2.GetType()</span></p>
<p style="text-align: justify;">e successivamente, recuperiamo i due oggetti <strong>PropertyInfo</strong> della <strong>property</strong> desiderata attraverso i due oggetti <strong>Type</strong> appena istanziati.</p>
<p><span style="font-family: courier new,courier;">PropertyInfo_obj1 = Type_obj1.GetProperty(m_propertyname)<br />
PropertyInfo_obj2 = Type_obj2.GetProperty(m_propertyname)</span></p>
<p style="text-align: justify;">A questo punto se uno dei due oggetti <strong>propertyInfo</strong> e a <strong>nothing</strong> vuol dire che la proprietà non esiste. (Attenzione al case sensitive)<br />
Proseguendo, andiamo a leggerne il valore e ad assegnarlo a due oggetti di tipo <strong>IComparable</strong>.</p>
<p><span style="font-family: courier new,courier;">Valueobj1 = PropertyInfo_obj1.GetValue(obj1, Nothing)<br />
Valueobj2 = PropertyInfo_obj2.GetValue(obj2, Nothing)</span></p>
<p style="text-align: justify;">Qui è importante ricordare che numerici, stringhe e date sono già ICompareble quindi assumiamo che la nostra <strong>property</strong> sia di questo tipo o sia un oggetto che comunque implementa l&#8217;interfaccia <strong>IComparable</strong>.<br />
Nel caso effettuiamo un controllo e se così&#8217; non fosse, solleviamo un eccezione.</p>
<p><span style="font-family: courier new,courier;">If Valueobj1 Is Nothing Then<br />
    &#8217; Property  non IComparable<br />
    Throw New Exception(&#8220;Property &#8221; &amp; m_propertyname &amp; &#8221; is not IComparable&#8221;)<br />
End If</span></p>
<p style="text-align: justify;">Il resto è semplice, usiamo il metodo <strong>CompareTo</strong> per capire quale dei due oggetti è il maggiore e la property <strong>Ascending</strong> per decidere se invertire o meno il risultato.</p>
<p style="text-align: justify;">Di seguito possiamo vederne il risultato:</p>
<p><span style="font-family: courier new,courier;">Dim myList As New ArrayList</span></p>
<p><span style="font-family: courier new,courier;">myList.Add(Product4)<br />
myList.Add(Product1)<br />
myList.Add(Product2)<br />
myList.Add(Product3)</span></p>
<p><span style="font-family: courier new,courier;">sSortedObject = &#8220;&#8221;<br />
<span style="color: #ff6600;">myComparer = New ComparerGeneralizedClass(&#8220;Name&#8221;, True)</span></span></p>
<p><span style="font-family: courier new,courier;"><span style="color: #ff6600;">myList.Sort(MyComparer)</span><br />
For Each obj In myList<br />
    sSortedObject &amp;= obj.Name &amp; vbCrLf<br />
Next<br />
MessageBox.Show(sSortedObject)</span></p>
<p><span style="font-family: courier new,courier;">sSortedObject = &#8220;&#8221;<br />
<span style="color: #ff6600;">myComparer = New ComparerGeneralizedClass(&#8220;Name&#8221;, False)<br />
myList.Sort(myComparer)<br />
</span>For Each obj In myList<br />
    sSortedObject &amp;= obj.Name &amp; vbCrLf<br />
Next<br />
MessageBox.Show(sSortedObject)<br />
<img class="aligncenter size-full wp-image-281" title="04_Comparer1" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/04_Comparer1.png" alt="" width="155" height="202" /></span></p>
<p><span style="font-family: courier new,courier;">&#8216; Volume<br />
sSortedObject = &#8220;&#8221;<br />
<span style="color: #ff6600;">myComparer = New ComparerGeneralizedClass(&#8220;GetVolume&#8221;, False)<br />
myList.Sort(myComparer</span>)<br />
For Each obj In myList<br />
    sSortedObject &amp;= obj.Name &amp; &#8221; Volume:&#8221; &amp; obj.GetVolume.ToString &amp; vbCrLf<br />
Next<br />
MessageBox.Show(sSortedObject)</span></p>
<p><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/04_Comparer2.png"><img class="aligncenter size-full wp-image-282" title="04_Comparer2" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/04_Comparer2.png" alt="" width="215" height="202" /></a></p>
<h4><span style="color: #0066cc;">In conclusione</span></h4>
<p style="text-align: justify;">Anche in questo caso è possibile apportare diverse migliorie alla nostra classe e soprattutto renderla un pochino più solida aggiungendo qualche controllo in più.</p>
<p style="text-align: justify;">In ogni caso abbiamo costruito un semplice <strong>prototipo riutilizzabile</strong>  che ci permette di ordinare i nostri oggetti potendo scegliere nome della property ed il verso di ordinamento.</p>
<p style="text-align: justify;">Al prossimo post. <img src='http://www.massimilianospinettipmp.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.massimilianospinettipmp.info/2010/10/rendiamo-i-nostri-oggetti-ordinabili/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clonare oggetti in .NET</title>
		<link>http://www.massimilianospinettipmp.info/2010/10/clonare-oggetti-in-net/</link>
		<comments>http://www.massimilianospinettipmp.info/2010/10/clonare-oggetti-in-net/#comments</comments>
		<pubDate>Fri, 08 Oct 2010 10:04:28 +0000</pubDate>
		<dc:creator>Massimiliano Spinetti</dc:creator>
				<category><![CDATA[Framework .NET]]></category>
		<category><![CDATA[Class]]></category>
		<category><![CDATA[Clone]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Object]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[Serializable]]></category>
		<category><![CDATA[VB.NET]]></category>

		<guid isPermaLink="false">http://www.massimilianospinettipmp.info/?p=170</guid>
		<description><![CDATA[Come implementare un metodo per la clonazione di oggetti in VB.NET. Quali le soluzioni possibili  e quali le differenze?   Difficoltà: Piattaforma: VB.NET  Durante lo sviluppo di alcune applicazioni, mi è capitato di dover creare istanze  che fossero copie esatte di un oggetto esistente.  Poiché  le classi non sono dei tipi valore, ovvero non ereditano dalla [...]]]></description>
			<content:encoded><![CDATA[<p><em>Come implementare un metodo per la clonazione di oggetti in VB.NET.<br />
Quali le soluzioni possibili  e quali le differenze? </em> </p>
<p><strong>Difficoltà</strong>:<a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/Valutazione-medio.png"><img class="alignnone size-full wp-image-179" title="Difficoltà media" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/Valutazione-medio.png" alt="" width="96" height="24" /></a><br />
<strong>Piattaforma:</strong> <span style="color: #008000;">VB.NET</span> </p>
<p style="text-align: justify;">Durante lo sviluppo di alcune applicazioni, mi è capitato di dover creare istanze  che fossero <strong>copie esatte</strong> di un oggetto esistente.  Poiché  le classi non sono dei tipi <strong>valore</strong>, ovvero non ereditano dalla classe <strong>System.ValueType</strong>, ma le loro istanze sono in realtà dei <strong>riferimenti all’oggetto</strong>,   le operazioni di assegnazione, non creano un duplicato dell’oggetto, ma bensì del riferimento.<br />
In questo post esploriamo due possibili modi per implementare un meccanismo  di <a title="Clone wikipedia" href="http://it.wikipedia.org/wiki/Clone#Informatica" target="_blank"><strong>clonazione</strong> </a>degli oggetti in . NET. </p>
<h4><span style="color: #006699;">Due parole sulla clonazione</span></h4>
<p style="text-align: justify;">Con <strong>clonazione</strong> si intende una copia esatta di un oggetto.  Mentre per i tipi valore e per le structure è possibile ottenere questo risultato attraverso una semplice assegnazione,  per duplicare un oggetto è necessario crearne una nuova istanza ed effettuare la copia di tutti i suoi attributi. </p>
<p>Un modo semplice, (ma non matematico) che possiamo usare  per capire se due istanze di  oggetti si stanno riferendo allo stesso dato o a due dati differenti,   è andare per esempio a confrontare  il <strong>codice Hash</strong>.</p>
<p><span style="font-family: courier new,courier;">MyObject.GetHashCode()</span></p>
<p><em>(attenzione, il codice Intero di Hash restituito dalla classe base Object non assicura l’univocità)</em></p>
<h4><span style="color: #006699;">Clonazione attraverso l&#8217;utilizzo di MemberWiseClone</span></h4>
<p style="text-align: justify;">Questo approccio prevedere l’implementazione da parte della nostra classe <strong>dell’interfaccia iCloneable</strong>. Questa interfaccia richiede che venga implementato un unico <strong>metodo Clone</strong> che restituisce un nuovo oggetto.<br />
All’interno del metodo Clone chiameremo il metodo <strong>protetto</strong> di <strong>system.Object MemberWiseClone</strong> che crea una copia di tutti i riferimenti dell’oggetto.</p>
<p style="text-align: justify;">In questo esempio molto semplice definiamo una classe <strong>ClonableAnimal</strong> come segue:</p>
<p><span style="font-family: courier new,courier;">Public Enum <strong>Species</strong><br />
    Dog<br />
    Cat<br />
    Bird<br />
End Enum</span><br />
 <br />
<span style="font-family: courier new,courier;">Public Class <strong>ClonableAnimal</strong><br />
  <strong><span style="color: #ff6600;">Implements ICloneable</span></strong><br />
</span></p>
<p><span style="font-family: courier new,courier;">Private m_Age As Integer<br />
Private m_Name As String<br />
Private m_AnimalType As Species<br />
Public ReadOnly Property Age() As Integer<br />
   Get<br />
      Return m_Age<br />
   End Get<br />
End Property<br />
Public Property Name() As String<br />
   Get<br />
      Return m_Name<br />
   End Get<br />
   Set(ByVal value As String)<br />
      m_Name = value<br />
   End Set<br />
End Property<br />
Public ReadOnly Property AnimalType() As Species<br />
   Get<br />
      Return m_AnimalType<br />
   End Get<br />
End Property<br />
 </span><br />
<span style="font-family: courier new,courier;">Public Sub New(ByVal NewName As String, ByVal NewAnimalType As Species)<br />
   m_Age = 0<br />
   m_Name = NewName<br />
   m_AnimalType = NewAnimalType<br />
End Sub<br />
Public Sub Addyear()<br />
   m_Age = m_Age + 1<br />
End Sub<br />
<span style="color: #ff6600;">Public Function Clone() As Object Implements System.ICloneable.Clone<br />
   Return Me.MemberwiseClone<br />
End Function</span><br />
Public Function GetDescription() As String<br />
   Return &#8220;MyName is: &#8221; &amp; m_Name &amp; &#8220;, My age is:&#8221; &amp; m_Age.ToString &amp; &#8221; and I am a &#8221; &amp; m_AnimalType.ToString<br />
End Function</span></p>
<p style="text-align: justify;">Questa classe è composta di: tre semplici <strong>property</strong>, un <strong>metodo clone</strong> che restituisce una nuova istanza dell’oggetto, un metodo <strong><em>Addyear()</em></strong> usato per incrementare la <strong><em>property Age</em></strong>, ed un metodo <strong><em>GetDescription()</em></strong> che restituisce il contenuto delle property dell’oggetto.</p>
<p style="text-align: justify;">A questo punto testiamo il metodo clone creando un oggetto <strong><em>MyAnimal1</em></strong> ed assegnando a <strong><em>MyAnimal2</em></strong> il valore restituito dal metodo Clone.</p>
<p><span style="font-family: courier new,courier;">Dim MyAnimal1 As ClonableAnima)<br />
Dim MyAnimal2 As ClonableAnimal<br />
MyAnimal1 = New ClonableAnimal(&#8220;Scooby Doo&#8221;, Species.Dog)<br />
MyAnimal1.Addyear()<br />
MyAnimal1.Addyear()<br />
MyAnimal2 = MyAnimal1.Clone</span></p>
<p style="text-align: justify;">Il risultato è effettivamente una <strong>copia esatta</strong> dell’oggetto poichè le property sono le stesse ma il <strong>codice Hash differisce</strong>.</p>
<p style="text-align: justify;"><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/image0012.png"><img class="aligncenter size-full wp-image-258" title="image001" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/image0012.png" alt="" width="465" height="182" /></a></p>
<p style="text-align: justify;">Considerando che molte classi in NET espongono già un metodo Clone, questo approccio sembrerebbe a prima vista il più semplice da implementare.<br />
E’ necessario però fare una considerazione, il metodo <strong>MemberWiseClone</strong> crea una<strong> copia dei riferimenti</strong>, questo vuol dire che nel caso in cui il nostro oggetto ha attributi di tipo valore, questi verranno correttamente duplicati, ma se uno o più dei sui attributi è sua volta un oggetto, allora di questi ne verrà <strong>copiato il riferimento</strong>.</p>
<p style="text-align: justify;">Prendiamo ad esempio la nuova classe:</p>
<p><span style="font-family: courier new,courier;">Public Class <strong>ClonableMaster</strong><br />
   <span style="color: #ff6600;">Implements ICloneable</span><br />
Private m_Name As String<br />
Private m_Pet As ClonableAnimal<br />
Public Property Name() As String<br />
   Get<br />
      Return m_Name<br />
   End Get<br />
   Set(ByVal value As String)<br />
      m_Name = value<br />
   End Set<br />
End Property<br />
<span style="color: #ff6600;">Public Property Pet() As ClonableAnimal<br />
   Get<br />
      Return m_Pet<br />
   End Get<br />
   Set(ByVal value As ClonableAnimal)<br />
      m_Pet = value<br />
   End Set<br />
End Property</span><br />
Public Sub New(ByVal HumanName As String, ByVal NewName As String, ByVal NewAnimalType As Species)<br />
   m_Name = HumanName<br />
   m_Pet = New ClonableAnimal(NewName, NewAnimalType)<br />
End Sub<br />
<span style="color: #ff6600;">Public Function Clone() As Object Implements System.ICloneable.Clone<br />
   Return Me.MemberwiseClone<br />
End Function</span><br />
End Class</span></p>
<p style="text-align: justify;">Anche questa classe implementa <strong>l’interfaccia iClonable</strong>, ma una delle sue property, la <strong><em>Pet</em></strong>, è di tipo <strong>ClonableAnimal</strong>.<br />
Nell’esempio che segue effettuiamo la clonazione sull’oggetto principale ed andando poi a verificare il risultato, possiamo vedere che, mentre gli attributi valore degli oggetti <strong>MyHuman1</strong> e <strong>MyHuman2</strong> sono stati copiati, la <strong><em>property Pet</em></strong> dei due oggetti punta allo stesso dato.</p>
<p><span style="font-family: courier new,courier;">Dim MyHuman1 As ClonableMaster<br />
Dim MyHuman2 As ClonableMaster<br />
MyHuman1 = New ClonableMaster(&#8220;Shaggy&#8221;, &#8220;Scooby Doo&#8221;, Species.Dog)<br />
MyHuman1.Pet.Addyear()<br />
MyHuman1.Pet.Addyear()<br />
<span style="color: #339966;">‘ cloniamo l’oggetto</span><br />
MyHuman2 = MyHuman1.Clone</span></p>
<p><span style="font-family: courier new,courier;"><span style="color: #339966;">‘ cambiamo la property name dell’oggetto incorporato Pet e ne incrementiamo la Age.</span><br />
</span><span style="font-family: courier new,courier;">MyHuman1.Pet.Name = &#8220;Scooby Doo 2&#8243;<br />
MyHuman1.Pet.Addyear()<br />
MyHuman1.Pet.Addyear()</span></p>
<p style="text-align: justify;">A questo punto possiamo verificare che in entrambe le istanze la <strong><em>property Pet</em></strong> è variata e che il <strong>codice Hash è lo stesso</strong></p>
<p style="text-align: justify;"><strong><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/image0021.png"><img class="aligncenter size-full wp-image-259" title="image002" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/image0021.png" alt="" width="500" height="191" /></a></strong></p>
<h4><span style="color: #006699;">Clonazione attraverso la serializzazione</span></h4>
<p style="text-align: justify;">Un&#8217;altra possibile soluzione prevede l’utilizzo della <strong><a title="Serializzazione Wikipedia" href="http://it.wikipedia.org/wiki/Serializzazione" target="_blank">serializzazione </a>dell’oggetto</strong> per poterne creare una copia esatta, ovvero in una prima fase viene fatta la trasformazione dell’oggetto in uno <strong>stream di bytes</strong>, e subito dopo viene fatta la <strong>deserializzazione</strong> in una nuova istanza di oggetto.</p>
<p style="text-align: justify;">Sebbene questa tecnica permetta la clonazione di oggetti che non espongono nessun metodo clone, è però necessario che l’oggetto stesso e tutti i suoi attributi siano serializzabili.<br />
E’ importante sottolineare che per essere serializzabile, una classe deve essere marcata con <strong>l’attributo Serializable</strong>, e che le sue eventuali classi padre <strong>siano serializzabili</strong>.</p>
<p style="text-align: justify;">Per verificarne il funzionamento creiamo le seguenti due classi :</p>
<p><span style="font-family: courier new,courier;"><span style="color: #ff6600;">&lt;Serializable()&gt; _<br />
</span>Public Class <strong>SerializableAnimal</strong><br />
Private m_Age As Integer<br />
Private m_Name As String<br />
Private m_AnimalType As Species<br />
Public ReadOnly Property Age() As Integer<br />
   Get<br />
      Return m_Age<br />
   End Get<br />
End Property<br />
Public Property Name() As String<br />
   Get<br />
      Return m_Name<br />
   End Get<br />
   Set(ByVal value As String)<br />
      m_Name = value<br />
   End Set<br />
End Property<br />
Public ReadOnly Property AnimalType() As Species<br />
   Get<br />
      Return m_AnimalType<br />
   End Get<br />
End Property<br />
Public Sub New(ByVal NewName As String, ByVal NewAnimalType As Species)<br />
   m_Age = 0<br />
   m_Name = NewName<br />
   m_AnimalType = NewAnimalType<br />
End Sub<br />
Public Sub Addyear()<br />
   m_Age = m_Age + 1<br />
End Sub<br />
Public Function GetDescription() As String<br />
   Return &#8220;MyName is: &#8221; &amp; m_Name &amp; &#8220;, My age is: &#8221; &amp; m_Age.ToString &amp; &#8221; and I am a &#8221; &amp; m_AnimalType.ToString<br />
End Function<br />
End Class</span></p>
<p style="text-align: justify;">Questa classe è identica alla precedente tranne che per il fatto che <strong>non implementa iCloneable</strong> ed è <strong>marcata serializable</strong></p>
<p style="text-align: justify;"><span style="font-family: courier new,courier;"><span style="color: #ff6600;">Imports System.Runtime.Serialization.Formatters.Binary<br />
&lt;Serializable()&gt; _</span><br />
Public Class SerializableMaster<br />
   Implements ICloneable<br />
Private m_Name As String<br />
Private m_Pet As SerializableAnimal<br />
Public Property Name() As String<br />
   Get<br />
      Return m_Name<br />
   End Get<br />
   Set(ByVal value As String)<br />
      m_Name = value<br />
   End Set<br />
End Property<br />
<span style="color: #ff6600;">Public Property Pet() As SerializableAnimal<br />
   Get<br />
      Return m_Pet<br />
   End Get<br />
   Set(ByVal value As SerializableAnimal)<br />
      m_Pet = value<br />
   End Set<br />
End Property<br />
</span>Public Sub New(ByVal HumanName As String, ByVal NewName As String, ByVal NewAnimalType As Species)<br />
   m_Name = HumanName<br />
   m_Pet = New SerializableAnimal(NewName, NewAnimalType)<br />
End Sub<br />
<span style="color: #ff6600;">Public Function Clone() As Object Implements System.ICloneable.Clone<br />
   Dim Formatter As New BinaryFormatter<br />
   Dim objMemorystrem As New System.IO.MemoryStream<br />
   Formatter.Serialize(objMemorystrem, Me)<br />
   objMemorystrem.Position = 0<br />
   Return Formatter.Deserialize(objMemorystrem)<br />
End Function</span><br />
End Class</span></p>
<p style="text-align: left;">In questo caso le <strong>differenze</strong> sono date dall’attributo <strong><em>&lt;Serializable()&gt;,</em></strong> dall’utilizzo del namespace <strong><em>System.Runtime.Serialization.Formatters.Binary</em></strong> e dal metodo <strong><em>Clone</em></strong>.</p>
<p>Al contrario del metodo precedente, la clonazione per serializzazione <strong>permette la clonazione</strong> anche di attributi oggetto.</p>
<p><span style="font-family: courier new,courier;">Dim MyHuman1 As SerializableMaster<br />
Dim MyHuman2 As SerializableMaster<br />
MyHuman1 = New SerializableMaster(&#8220;Shaggy&#8221;, &#8220;Scooby Doo&#8221;, Species.Dog)<br />
MyHuman1.Pet.Addyear()<br />
MyHuman1.Pet.Addyear()<br />
<span style="color: #339966;">‘ Cloniamo l’oggetto</span><br />
MyHuman2 = MyHuman1.Clone<br />
<span style="color: #339966;">‘ cambiamo la property name dell’oggetto incorporato Pet e ne incrementiamo la Age.</span></span></p>
<p><span style="font-family: courier new,courier;">MyHuman1.Pet.Name = &#8220;Scooby Doo 2&#8243;<br />
MyHuman1.Pet.Addyear()<br />
MyHuman1.Pet.Addyear()</span></p>
<p>In questo caso le modifiche post clonazione hanno riguardato solo uno dei due oggetti.</p>
<p><a href="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/image0031.png"><img class="aligncenter size-full wp-image-260" title="image003" src="http://www.massimilianospinettipmp.info/wp-content/uploads/2010/10/image0031.png" alt="" width="500" height="191" /></a></p>
<h4><span style="color: #006699;">In Conclusione</span></h4>
<p>Abbiamo visto <strong>due possibili approcci</strong> all’implementazione di un sistema di clonazione. Entrambe le soluzione presentano <strong>pregi</strong> e <strong>difetti</strong>, quindi può non essere del tutto corretto preferire a priori un metodo piuttosto che l’altro.</p>
<p>Va inoltre considerato che questo è solo uno spunto, ed entrambe le soluzione possono essere largamente migliorate.</p>
<p>Per esempio per quanto riguarda la clonazione attraverso <strong>MemberwiseClone</strong>, un ulteriore passo può essere quello di utilizzare la <strong>reflection</strong> per scorrere all’interno del metodo clone i vari field dell’oggetto, testare se sono <strong>iCloneable</strong> e nel caso, chiamare <strong>ricorsivamente</strong> il metodo clone.</p>
<p>Per quanto riguarda la soluzione che utilizza la serializzazione invece, andrebbe previsto l’inserimento di un controllo che verifichi che l’oggetto sia effettivamente serializzabile.</p>
<p>Al prossimo post. <img src='http://www.massimilianospinettipmp.info/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.massimilianospinettipmp.info/2010/10/clonare-oggetti-in-net/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Uno, Due, Thread&#8230; si parte</title>
		<link>http://www.massimilianospinettipmp.info/2010/10/uno-due-thread-si-parte/</link>
		<comments>http://www.massimilianospinettipmp.info/2010/10/uno-due-thread-si-parte/#comments</comments>
		<pubDate>Fri, 01 Oct 2010 15:05:37 +0000</pubDate>
		<dc:creator>Massimiliano Spinetti</dc:creator>
				<category><![CDATA[Generale]]></category>

		<guid isPermaLink="false">http://www.massimilianospinettipmp.info/?p=161</guid>
		<description><![CDATA[Finalmente eccoci qui, al primo post. Questo blog nasce dal desiderio di condividere la propria esperienza, dalla passione per il proprio lavoro, e sicuramente e non ultima, dalla voglia di potersi confrontare. Una definizione che ho trovato in rete e che mi piace molto è questa: &#8220;I blog sono un modo estremamente dinamico e veloce [...]]]></description>
			<content:encoded><![CDATA[<p>Finalmente eccoci qui, al primo post. </p>
<p>Questo blog nasce dal desiderio di condividere la propria esperienza,  dalla passione per il proprio lavoro, e sicuramente e non ultima,  dalla voglia di potersi <strong>confrontare</strong>.</p>
<p>Una definizione che ho trovato in rete e che mi piace molto è questa:<br />
<em>&#8220;I blog sono un modo estremamente dinamico e veloce per entrare nelle discussioni degli utenti, fornire suggerimenti e consigli e ricevere feedback.&#8221; </em></p>
<p><em><strong>Si ma di cosa parlerà?</strong></em><br />
Mi piace l&#8217;idea di non pormi dei vincoli, parleremo di ciò che ruota intorno al mondo della programmazione, idee e spunti tecnici, ma anche metodologie, approcci alla risoluzione dei problemi e qualche volta spero mi concediate anche qualche divagazione.</p>
<p>e allora via, ci vediamo al prossimo post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.massimilianospinettipmp.info/2010/10/uno-due-thread-si-parte/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

