Visualizzazione post con etichetta C#. Mostra tutti i post
Visualizzazione post con etichetta C#. Mostra tutti i post

lunedì 1 giugno 2015

Mono 4.0 e C# 6.0

Mono 4.0 è la prima versione di Mono che contiene codice Microsoft .NET open source. In questa versione sono abilitate per default le nuove funzionalità del C# 6.0.

Queste sono le nuove funzionalità

  • Auto property initializers
  • Static members
  • String interpolation
  • Expression-bodied methods
  • Expression-bodied properties
  • Index initializers
  • Null-conditional operators
  • The nameof operator
  • Exception filters
  • Await in catch and finally

E questo un esempio di utilizzo (ho usato MonoDevelop 5.9)

using System;
using Newtonsoft.Json.Linq;
using System.Configuration;

//Con - Static members
using static System.Math;

namespace Azzan.Mono4Sample
{
    public class Point
    {
        /*
        //Prima di - Auto property initializers
        public int X {get; private set;}
        public int Y {get; private set;}

        public Point()
        {
            X = 4;
            Y = 9;
        }
        */

        //Con - Auto property initializers
        public int X {get; } = 4;
        public int Y {get; } = 9;

        public Point(int x, int y) { X = x; Y = y; }

        //Prima di Expression-bodied properties
        /*
        public double Dist
        {
            //Prima di - Static members
            //get { return Math.Sqrt(X * X + Y * Y); }

            //Con - Static members
            get { return Sqrt(X * X + Y * Y); }
        }
        */

        //Con - Expression-bodied properties
        public double Dist => Sqrt(X * X + Y * Y);

        //Prima di - Expression-bodied methods
        /*
        public override string ToString()
        {
            //Prima di - String interpolation
            //return string.Format("[Point: X={0}, Y={1}, Dist={2}]", X, Y, Dist);

            //Con - String interpolation
            return $"[Point: X={X}, Y={Y}, Dist={Dist}]";
        }
        */

        //Con - Expression-bodied methods
        public override string ToString() => $"[Point: X={X}, Y={Y}, Dist={Dist}]"; 

        //Prima di - Index initializers
        /*
        public JObject ToJson()
        {
            var result = new JObject();
            result["x"]  = X;
            result["y"]  = Y;
            return result;
        }
        */

        //Con - Index initializers
        public JObject ToJson() => new JObject() { ["x"]  = X, ["y"]  = Y };

        //Prima di - Null-conditional operators
        /*
        public static Point FromJson(JObject json)
        {
            if(json != null &&
                json["x"] != null &&
                json["x"].Type  == JTokenType.Integer &&
                json["y"] != null &&
                json["y"].Type  == JTokenType.Integer)
            {
                return new Point((int)json["x"], (int)json["y"]);
            }

            return null;
        }
        */

        //Con - Null-conditional operators
        public static Point FromJson(JObject json)
        {
            if(json?["x"]?.Type == JTokenType.Integer &&
               json?["y"]?.Type == JTokenType.Integer)
            {
                return new Point((int)json["x"], (int)json["y"]);
            }

            return null;
        }
            
        public Point Add(Point point)
        {
            if(point == null)
            {
                //Prima di - The nameof operator
                //throw new ArgumentNullException("point");

                //Con - The nameof operator
                throw new ArgumentNullException(nameof(point));
            }

            return point;
        }

        public void DoSomething()
        {
            //Prima di - Exception filters
            try
            {
                
            }                                //Con - Exception filters
            catch(ConfigurationException ex) //when (ex.IsSevere)
            {
                //Con - Await in catch and finally
                //await LogAsync(ex);
            }
            finally 
            {
                //Con - Await in catch and finally
                //await CloseAsync();
            }
        }
    }
}
Qui trovate i sorgenti dell'esempio creati con MonoDevelop 5.9: Download esempio

Purtroppo ho notato però che l'editor di MonoDevelop 5.9 ha ancora qualche problema nel riconoscere la sintassi C# 6.0 ma non sono cose gravi.
Invece gli "Exception filters" proprio non funzionano, se de-commentate il codice del mio esempio il compilatore vi da errore.

Che versione di Mono è installata?


Questo è un comando che potete lanciare tramite shell Linux, per vedere i dettagli della versione che avete installato:

mono --version

venerdì 4 luglio 2014

From C# to Qt: Thread sleep

Eccomi alla prima parte della rubrica dedicata al confronto fra C# e Qt. In C# quando vogliamo mettere in pausa il thread corrente in cui ci troviamo per tot millisecondi usiamo la funzione statica: Thread.Sleep([numero di millisecondi]).
In Qt invece ci sono almeno 3 possibilità diverse:
//METODO 1:
//Usare la classe QTest
QTest::qSleep(100); // blocca l' event processing
QTest::qWait(100);  // non blocca l' event processing

//METODO 2:
//Usare QWaitCondition / QMutex
QWaitCondition waitCondition;
QMutex mutex;

waitCondition.wait(&mutex, 100);

//METODO 3:
//Oppure fare derivare la nostra classe da QThread.
class Thread : public QThread
{
public:
    static void msleep(int ms)
    {
        QThread::msleep(ms);
    }
};

Thread::msleep(100);

mercoledì 5 settembre 2012

Rimuovere elementi da una lista in maniera intelligente

Di solito quando vogliamo fare eseguire un operazione e poi rimuovere degli elementi da una lista, come facciamo?

Verrebbe naturale di fare un ciclo su ogni elemento della lista, eseguire l’operazione e rimuovere l’elemento:

foreach (Command c in itsCommands)
{        
    c.Execute();
    itsCommands.Remove(c);
}

Purtroppo però così facendo otteniamo un eccezione che ci avvisa che la collezione è stata modificata (in effetti abbiamo rimosso un elemento) e quindi l’operazione di ciclo sulla collezione non è più valida.

Come soluzione al problema si potrebbe crea un altra collezione con gli elementi da rimuovere ed eseguire un altro ciclo per eliminare i comandi eseguiti:

Commands itsCommandsForDelete = new Commands();

foreach (Command c in itsCommands)
{
    c.Execute();
    itsCommandsForDelete.Add(c);
}

foreach (Command c in itsCommandsForDelete)
{
    itsCommands.Remove(c);
}

Questa soluzione non è molto performante perchè ci obbliga ad eseguire il ciclo su ogni elemento per due volte.

Ecco una soluzione alternativa per eseguire il tutto in un solo ciclo:

while (itsCommands.Count > 0)
{
    Command c = (Command) itsCommands[0];
    itsCommands.RemoveAt(0);
    c.Execute();
}

venerdì 27 gennaio 2012

String format .NET semplificato e naturale

Molte volte ci troviamo a dover inserire delle stringhe in una stringa più grande (di solito una frase, per notificare un messaggio all’utente dell’applicazione).
Per fare ciò usiamo il metodo “String.Format()” che accetta in input la stringa da formattare, e un array contenete le altre stringhe da inserire, al posto di segna posti speciali, costruiti con la regola: {indice dell’array}.
Es.:
MessageBox.Show(String.Format("Errore numero {0}, l'utente {1}, non ha i permessi di lettura del file
 {2}, inoltre {1}, non appartiene al ruolo {3}", new String[]{"123", "Mario", "file.txt", "admin"}));
Di solito la scrittura di questo codice avviene nella seguente maniera:
  1. Si scrive: MessageBox.Show(
  2. Si pensa al messaggio e si inizia a scriverlo: "Errore numero …
  3. Ci si accorge che il messaggio dovrà contenere dei pezzi di stringa all’interno della stringa principale.
  4. Si aggiungono i segna posto per i pezzi di stringa: numero {0}, l'utente {1}, non
  5. Completata la frase, ci si posiziona all’inizio della frase stessa.
  6. Si digita String.Format(
  7. Si va alla fine della frase e si chiude la parentesi )
Come si vede a lungo andare si perde molto tempo a compiere tale operazione e non è del tutto naturale, perché ci impegna a cercare l’inizio della frase scritta per aggiungere un pezzo di codice e a tornare alla fine di essa, per chiudere la parentesi.
Per risparmiare tempo e trovare più naturalezza nella scrittura, ho implementato la seguente classe per estendere la classe System.String:
namespace System
{
    /// <summary>
    /// Estensioni per le classi stringa
    /// </summary>
    public static class StringEx
    {
        /// <summary>
        /// Formatta la stringa
        /// </summary>
        /// <param name="pValue">Stringa</param>
        /// <param name="args">Parametri</param>
        /// <returns>Stringa formattata</returns>
        public static string Formatting(this String pValue, params object[] args)
        {
            return String.Format(pValue, args);
        }

        /// <summary>
        /// Formatta la stringa
        /// </summary>
        /// <param name="pValue">Stringa</param>
        /// <param name="format">Format provider</param>
        /// <param name="args">Parametri</param>
        /// <returns>Stringa formattata</returns>
        public static string Formatting(this String pValue, IFormatProvider format, params object[] args)
        {
            return String.Format(format, pValue, args);
        }
    }
}
Ora potere scrivere lo stesso codice dell’esempio di prima in maniera naturale, senza bisogno di tornare a cercare dove inizia la vostra Stringa:
MessageBox.Show("Errore numero {0}, l'utente {1}, non ha i permessi di lettura del file {2}, inoltre {1},
 non appartiene al ruolo {3}".Formatting(new String[] { "123", "Mario", "file.txt", "admin" }));

sabato 14 gennaio 2012

Implementare il Databindings di oggetti

Oggi mi è capitato di dover implementare il databindings di un controllo che ne era sprovvisto (il treenode). Per aggiungere il databindings ad un oggetto TreeNode, come nel mio caso, ma anche per qualsiasi altro oggetto, basta implementare l’interfaccia IBindableComponent.

In questo modo potete usare il Binding su tutte le proprietà del TreeNode; in particolare a me interessava collegare la proprietà “Name” di un mio oggetto alla proprietà “Text” di un TreeNode.

Ecco un esempio in C# dell’implementazione del databindings per la proprietà “Text” di un oggetto TreeNode:
public class TreeNodeBind : TreeNode, IBindableComponent
    {
        //Implementazione dei costruttori base
        public TreeNodeBind()
            : base()
        {
        }

        public TreeNodeBind(string text) 
            : base(text)
        {
        }

        public TreeNodeBind(string text, TreeNode[] children)
            : base(text, children)
        {
        }

        public TreeNodeBind(string text, int imgIndex, int selImgIndex) 
            : base(text, imgIndex, selImgIndex)
        {
        }

        public TreeNodeBind(string text, int imgIndex, int selImgIndex, TreeNode[] children)
            : base(text, imgIndex, selImgIndex, children)
        {
        }

        //Implementazione di IBindableComponent
        #region IBindableComponent Members

        private BindingContext _bindingContext;
        private ControlBindingsCollection _dataBindings;

        [Browsable(false)]
        public BindingContext BindingContext
        {
            get
            {
                if (_bindingContext == null)
                {
                    _bindingContext = new BindingContext();
                }
                return _bindingContext;
            }
            set
            {
                _bindingContext = value;
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ControlBindingsCollection DataBindings
        {
            get { return _dataBindings ?? (_dataBindings = new ControlBindingsCollection(this)); }
        }

        public ISite Site { get; set; }

        public event EventHandler Disposed;

        public void Dispose()
        {
            if (Disposed != null)
                Disposed(this, EventArgs.Empty);
        }

        #endregion
    }
Ora potete creare ed usare nodi di tipo TreeNodeBind che supportano il Binding:
TreeNodeBind nodoBind = new TreeNodeBind();
nodoBind.DataBindings.Add(new System.Windows.Forms.Binding("Text", oggettoConDati, "Name", true));
tree.Nodes.Add(nodoBind);

venerdì 9 dicembre 2011

Factory Method Design Pattern in pratica

Il Factory Method, fa parte dei creational patterns, esso consente di utilizzare un'interfaccia per la creazione di un oggetto, ma sono le sottoclassi a decidere quale classe istanziare.
L’obbiettivo principale è l’estensibilità, consente di istanziare un oggetto senza specificare una classe.
Il Factory Method è spesso utilizzato in applicazioni che:
  • necessitano che la creazione o la rappresentazione di oggetti sia nascosta ed indipendente dalla struttura principale.
  • gestiscono, mantengono, o manipolano collezioni di oggetti diverse, ma con molte caratteristiche in comune.
  • se il sistema principale viene modificato si possono modificare facilmente anche le caratteristiche comuni fra gli oggetti
  • forniscono una libreria di classi in cui è visibile solo l’interfaccia, ma non l’implementazione della classe
Ci sono 3 regole principali che il pattern Factory Method deve rispettare:
  1. Il metodo crea un nuovo oggetto
  2. Il metodo ritorna una classe astratta o un interfaccia
  3. La classe astratta o l’interfaccia viene implementata da più classi

Ora vediamo un piccolo esempio di implementazione per capire meglio come funziona il pattern Factory Method nei seguenti linguaggi:
(questi ultimi due comunque non supportano interfacce o classi astratte, quindi bisogna prestare la massima attenzione all’implementazione, magari usando una buona convenzione sui nomi delle classi e dei metodi, in maniera di evitare di utilizzare classi o metodi sbagliati per distrazione)

Diagramma UML:
In un nuovo progetto di tipo Console aggiungo il file “Persona” e creo la classe persona (questa classe sarà usata anche nei miei prossimi post sui design patterns):
//C#
using System;

namespace Netrudy.Patterns
{
    //Classe che rappresenta una persona fisica
    class Persona
    {
        //Costruttore
        public Persona(string nome, string cognome)
        {
            this.Nome = nome;
            this.Cognome = cognome;
        }

        //Nome
        public String Nome { get; set; }

        //Cognome
        public String Cognome { get; set; }
    }
}
'VB.NET
Namespace Netrudy.Patterns
    'Classe che rappresenta una persona fisica
    Class Persona
        'Costruttore
        Public Sub New(nome As String, cognome As String)
            Me.Nome = nome
            Me.Cognome = cognome
        End Sub

        'Nome
        Public Property Nome() As [String]
            Get
                Return m_Nome
            End Get
            Set(value As [String])
                m_Nome = value
            End Set
        End Property
        Private m_Nome As [String]

        'Cognome
        Public Property Cognome() As [String]
            Get
                Return m_Cognome
            End Get
            Set(value As [String])
                m_Cognome = value
            End Set
        End Property
        Private m_Cognome As [String]
    End Class
End Namespace
//Java
package Netrudy.Patterns;

//Classe che rappresenta una persona fisica
public class Persona
{
    //Costruttore
    public Persona(String nome, String cognome)
    {
        this.setNome(nome);
        this.setCognome(cognome);
    }

    //Nome
    private String privateNome;
    public final String getNome()
    {
        return privateNome;
    }
    public final void setNome(String value)
    {
        privateNome = value;
    }

    //Cognome
    private String privateCognome;
    public final String getCognome()
    {
        return privateCognome;
    }
    public final void setCognome(String value)
    {
        privateCognome = value;
    }
}
//C++/CLI file .h
#pragma once

using namespace System;

namespace Netrudy
{
    namespace Patterns
    {
        //Classe che rappresenta una persona fisica
        private ref class Persona
        {
            //Costruttore
        public:
            Persona(String ^nome, String ^cognome);

            //Nome
            property String ^Nome;

            //Cognome
            property String ^Cognome;
        };
    }
}

//file .cpp
#include "Persona.h"

using namespace System;
namespace Netrudy
{
    namespace Patterns
    {

        Persona::Persona(String ^nome, String ^cognome)
        {
            this->Nome = nome;
            this->Cognome = cognome;
        }
    }
}
//C++ Nativo file .h
#pragma once

#include <string>

namespace Netrudy
{
    namespace Patterns
    {
        //Classe che rappresenta una persona fisica
        class Persona
        {
            //Costruttore
        public:
            Persona(const std::string &nome, const std::string &cognome);

            //Nome
            private:
                std::string privateNome;
            public:
                std::string getNome();
                void setNome(const std::string &value);

            //Cognome
            private:
                std::string privateCognome;
            public:
                std::string getCognome();
                void setCognome(const std::string &value);
        };
    }
}

//file .cpp
#include "Persona.h"

namespace Netrudy
{
    namespace Patterns
    {

        Persona::Persona(const std::string &nome, const std::string &cognome)
        {
            this->Nome = nome;
            this->Cognome = cognome;
        }

        std::string Persona::getNome()
        {
            return privateNome;
        }

        void Persona::setNome(const std::string &value)
        {
            privateNome = value;
        }

        std::string Persona::getCognome()
        {
            return privateCognome;
        }

        void Persona::setCognome(const std::string &value)
        {
            privateCognome = value;
        }
    }
}
#Python
"""Classe che rappresenta una persona fisica"""
class Persona(object):
    
    #Costruttore
    def __init__(self, nome, cognome):
        self._nome = nome
        self._cognome = cognome

    #Nome
    def getNome(self):
        return self._nome

    def setNome(self, value):
        self._nome = value

    Nome = property(getNome, setNome)

    #Cognome
    def getCognome(self):
        return self._cognome

    def setCognome(self, value):
        self._cognome = value

    Cognome = property(getCognome, setCognome)
//Javascript
//Classe che rappresenta una persona fisica
//Costruttore
Netrudy.Patterns._persona = function Netrudy_Patterns__persona(nome, cognome) {
    this.set_nome(nome);
    this.set_cognome(cognome);
}
Netrudy.Patterns._persona.prototype = {
    //Nome
    _nome: null,
    
    get_nome: function Netrudy_Patterns__persona$get_nome() {
        return this._nome;
    },
    set_nome: function Netrudy_Patterns__persona$set_nome(value) {
        this._nome = value;
        return value;
    },
    
    //Cognome
    _cognome: null,
    
    get_cognome: function Netrudy_Patterns__persona$get_cognome() {
        return this._cognome;
    },
    set_cognome: function Netrudy_Patterns__persona$set_cognome(value) {
        this._cognome = value;
        return value;
    }
}
N.B.: Per Javascript ho usato Script#: http://projects.nikhilk.net/ScriptSharp alcune funzioni utilizzano parte di codice della libreria “mscorlib.js” di Script#, che è un misto di AJAX e funzioni di .NET Framework riadattate al Javascript (per esempio le collezioni Enumerable).
Aggiungiamo il file “FactoryMethod” e iniziamo a scrivere il seguente codice:
Dichiaro gli oggetti dipendente e datore di lavoro che derivano da persona (e rappresentano delle persone fisiche) questi sono i nostri oggetti nascosti:
//C#
//Personale di tipo: dipendente
class ConcreteDipendente : Persona
{
    public ConcreteDipendente(string nome, string cognome)
        : base(nome, cognome) {}
}

//Personale di tipo: datore di lavoro
class ConcreteDatoreDiLavoro : Persona
{
    public ConcreteDatoreDiLavoro(string nome, string cognome)
        : base(nome, cognome) {}
}
'VB.NET
'Personale di tipo: dipendente
Class ConcreteDipendente
    Inherits Persona
    Public Sub New(nome As String, cognome As String)
        MyBase.New(nome, cognome)
    End Sub
End Class

'Personale di tipo: datore di lavoro
Class ConcreteDatoreDiLavoro
    Inherits Persona
    Public Sub New(nome As String, cognome As String)
        MyBase.New(nome, cognome)
    End Sub
End Class
//Java
//Personale di tipo: datore di lavoro
public class ConcreteDatoreDiLavoro extends Persona
{
    public ConcreteDatoreDiLavoro(String nome, String cognome)
    {
        super(nome, cognome);
    }
}

//Personale di tipo: dipendente
public class ConcreteDipendente extends Persona
{
    public ConcreteDipendente(String nome, String cognome)
    {
        super(nome, cognome);
    }
}
//C++/CLI file .h
//Personale di tipo: dipendente
private ref class ConcreteDipendente : Persona
{
public:
    ConcreteDipendente(String ^nome, String ^cognome);
};

//Personale di tipo: datore di lavoro
private ref class ConcreteDatoreDiLavoro : Persona
{
public:
    ConcreteDatoreDiLavoro(String ^nome, String ^cognome);
};

//file .cpp
ConcreteDipendente::ConcreteDipendente(String ^nome, String ^cognome) : Persona(nome, cognome)
{
}

ConcreteDatoreDiLavoro::ConcreteDatoreDiLavoro(String ^nome, String ^cognome) : Persona(nome, cognome)
{
}
//C++ Nativo file .h
//Personale di tipo: dipendente
class ConcreteDipendente : public Persona
{
public:
    ConcreteDipendente(const std::string &nome, const std::string &cognome);
};

//Personale di tipo: datore di lavoro
class ConcreteDatoreDiLavoro : public Persona
{
public:
    ConcreteDatoreDiLavoro(const std::string &nome, const std::string &cognome);
};

// file .cpp
ConcreteDipendente::ConcreteDipendente(const std::string &nome, const std::string &cognome) : Persona(nome, cognome)
{
}

ConcreteDatoreDiLavoro::ConcreteDatoreDiLavoro(const std::string &nome, const std::string &cognome) : Persona(nome, cognome)
{
}
#Python
#Personale di tipo: dipendente
class ConcreteDipendente(Persona):

    def __init__(self, nome, cognome):
        Persona.__init__(self, nome, cognome)
        
#Personale di tipo: datore di lavoro
class ConcreteDatoreDiLavoro(Persona):

    def __init__(self, nome, cognome):
        Persona.__init__(self, nome, cognome)
//Javascript
//Personale di tipo: dipendente
Netrudy.Patterns._concreteDipendente = function Netrudy_Patterns__concreteDipendente(nome, cognome) {
    Netrudy.Patterns._concreteDipendente.initializeBase(this, [ nome, cognome ]);
}
//Personale di tipo: datore di lavoro
Netrudy.Patterns._concreteDatoreDiLavoro = function Netrudy_Patterns__concreteDatoreDiLavoro(nome, cognome) {
    Netrudy.Patterns._concreteDatoreDiLavoro.initializeBase(this, [ nome, cognome ]);
}
Come possiamo notare se c’è un costruttore nella classe base (persona) è necessario implementarlo anche nelle classi derivate.
Queste due classi appena create sono quelle concrete, cioè quelle con i campi e i metodi delle persone, e verranno create o meno a seconda di cosa scriveremo nel metodo di creazione FactoryMethod che implementeremo derivando la nostra nuova classe dalla seguente classe astratta:
//C#
//Classe astratta che rappresenta il personale dell'azienda
abstract class PersonaleAziendaCreator
{
    //Costruttore che chiama il metodo astratto
    //FactoryMethod
    //che verrà implementato nella classe figlia
    protected PersonaleAziendaCreator()
    {
        Persone = new List();
        this.FactoryMethod();
    }

    //Metodo astratto da implementare
    protected abstract void FactoryMethod();

    //Lista del personale aziendale (che sarà legato
    //alla categoria della classe figlia)
    public List Persone { get; protected set; }
}
'VB.NET
'Classe astratta che rappresenta il personale dell'azienda
MustInherit Class PersonaleAziendaCreator
    'Costruttore che chiama il metodo astratto FactoryMethod
    'che verrà implementato nella classe figlia
    Protected Sub New()
        Persone = New List(Of Persona)()
        Me.FactoryMethod()
    End Sub

    'Metodo astratto da implementare
    Protected MustOverride Sub FactoryMethod()

    'Lista del personale aziendale (che sarà legato alla categoria della classe figlia)
    Public Property Persone() As List(Of Persona)
        Get
            Return m_Persone
        End Get
        Protected Set(value As List(Of Persona))
            m_Persone = Value
        End Set
    End Property
    Private m_Persone As List(Of Persona)
End Class
//Java
//Classe astratta che rappresenta il personale dell'azienda
public abstract class PersonaleAziendaCreator
{
    //Costruttore che chiama il metodo astratto FactoryMethod
    //che verrà implementato nella classe figlia
    protected PersonaleAziendaCreator()
    {
        setPersone(new java.util.ArrayList<Persona>());
        this.FactoryMethod();
    }

    //Metodo astratto da implementare
    protected abstract void FactoryMethod();

    //Lista del personale aziendale (che sarà legato alla categoria della classe figlia)
    private java.util.ArrayList<Persona> privatePersone;
    public final java.util.ArrayList<Persona> getPersone()
    {
        return privatePersone;
    }
    protected final void setPersone(java.util.ArrayList<Persona> value)
    {
        privatePersone = value;
    }
}
//C++/CLI file .h
//Classe astratta che rappresenta il personale dell'azienda
private ref class PersonaleAziendaCreator abstract
{
    //Costruttore che chiama il metodo astratto FactoryMethod
    //che verrà implementato nella classe figlia
protected:
    PersonaleAziendaCreator();

    //Metodo astratto da implementare
    virtual void FactoryMethod() abstract;

    //Lista del personale aziendale (che sarà legato alla categoria della classe figlia)
public:
    property List<Persona^> ^Persone;
};

//file .cpp
PersonaleAziendaCreator::PersonaleAziendaCreator()
{
    Persone = gcnew List<Persona^>();
    this->FactoryMethod();
}
//C++ Nativo file .h
//Classe astratta che rappresenta il personale dell'azienda
class PersonaleAziendaCreator
{
    //Costruttore che chiama il metodo astratto FactoryMethod
    //che verrà implementato nella classe figlia
protected:
    PersonaleAziendaCreator();

    //Metodo astratto da implementare
    virtual void FactoryMethod() = 0;

    //Lista del personale aziendale (che sarà legato alla categoria della classe figlia)
    private:
        std::vector<Persona*> privatePersone;
    public:
        std::vector<Persona*> getPersone();
        void setPersone(std::vector<Persona*> value);
};

//file .cpp
PersonaleAziendaCreator::PersonaleAziendaCreator()
{
    Persone = std::vector<Persona*>();
    this->FactoryMethod();
}

std::vector<Persona*> PersonaleAziendaCreator::getPersone()
{
    return privatePersone;
}

void PersonaleAziendaCreator::setPersone(std::vector<Persona*> value)
{
    privatePersone = value;
}
#Python
"""Classe astratta che rappresenta il personale dell'azienda"""
#Python non supporta interfacce o classi astratte quindi utilizziamo il seguente workaround
class PersonaleAziendaCreator(object):

def __init__(self):
    self._persone = []
    self.FactoryMethod()

#workaround per metodo astratto
def FactoryMethod(self, arg):
    raise NotImplementedError("Metodo astratto!")

def getPersone(self):
    return self._persone

def setPersone(self, value):
    self._persone = value

Persone = property(getPersone, setPersone)
//Javascript
//Classe che rappresenta il personale dell'azienda
Netrudy.Patterns._personaleAziendaCreator = function Netrudy_Patterns__personaleAziendaCreator() {
    this.set_persone([]);
    //Metodo astratto da implementare
    this.factoryMethod();
}
Netrudy.Patterns._personaleAziendaCreator.prototype = {
    _persone: null,
    
    //Lista del personale aziendale (che sarà legato alla categoria della classe figlia)
    get_persone: function Netrudy_Patterns__personaleAziendaCreator$get_persone() {
        return this._persone;
    },
    set_persone: function Netrudy_Patterns__personaleAziendaCreator$set_persone(value) {
        this._persone = value;
        return value;
    }
}
Ora creiamo le classi di creazione del personale dell’azienda che implementeranno il FactoryMethod poiché derivando dalla classe base PersonaleAziendaCreator:
//C#
//Classe che si occupa di creare i dipendenti
//dell'azienda
class ConcreteCreatorDipendente : PersonaleAziendaCreator
{
    protected override void FactoryMethod()
    {
        Persone.Add(new ConcreteDipendente("Luigi", "Bross"));
        Persone.Add(new ConcreteDipendente("Toad", "Fungo"));
    }
}



//Classe che si occupa di creare i datori di lavoro 
//dell'azienda
class ConcreteCreatorDatoreDiLavoro : PersonaleAziendaCreator
{
    protected override void FactoryMethod()
    {
        Persone.Add(new ConcreteDatoreDiLavoro("Mario", "Boss"));
    }
}
'VB.NET
'Classe che si occupa di creare i dipendenti dell'azienda
Class ConcreteCreatorDipendente
    Inherits PersonaleAziendaCreator
    Protected Overrides Sub FactoryMethod()
        Persone.Add(New ConcreteDipendente("Luigi", "Bross"))
        Persone.Add(New ConcreteDipendente("Toad", "Fungo"))
    End Sub
End Class

'Classe che si occupa di creare i datori di lavoro dell'azienda
Class ConcreteCreatorDatoreDiLavoro
    Inherits PersonaleAziendaCreator
    Protected Overrides Sub FactoryMethod()
        Persone.Add(New ConcreteDatoreDiLavoro("Mario", "Boss"))
    End Sub
End Class
//Java
//Classe che si occupa di creare i dipendenti dell'azienda
public class ConcreteCreatorDipendente extends PersonaleAziendaCreator
{
    @Override
    protected void FactoryMethod()
    {
        getPersone().add(new ConcreteDipendente("Luigi", "Bross"));
        getPersone().add(new ConcreteDipendente("Toad", "Fungo"));
    }
}

//Personale di tipo: datore di lavoro
public class ConcreteDatoreDiLavoro extends Persona
{
    public ConcreteDatoreDiLavoro(String nome, String cognome)
    {
        super(nome, cognome);
    }
}
//C++/CLI file .h
//Classe che si occupa di creare i dipendenti dell'azienda
private ref class ConcreteCreatorDipendente : PersonaleAziendaCreator
{
protected:
    virtual void FactoryMethod() override;
};

//Classe che si occupa di creare i datori di lavoro dell'azienda
private ref class ConcreteCreatorDatoreDiLavoro : PersonaleAziendaCreator
{
protected:
    virtual void FactoryMethod() override;
};

//file .cpp
void ConcreteCreatorDipendente::FactoryMethod()
{
    Persone->Add(gcnew ConcreteDipendente("Luigi", "Bross"));
    Persone->Add(gcnew ConcreteDipendente("Toad", "Fungo"));
}

void ConcreteCreatorDatoreDiLavoro::FactoryMethod()
{
    Persone->Add(gcnew ConcreteDatoreDiLavoro("Mario", "Boss"));
}
//C++ Nativo file .h
//Classe che si occupa di creare i dipendenti dell'azienda
class ConcreteCreatorDipendente : public PersonaleAziendaCreator
{
protected:
    virtual void FactoryMethod();
};

//Classe che si occupa di creare i datori di lavoro dell'azienda
class ConcreteCreatorDatoreDiLavoro : public PersonaleAziendaCreator
{
protected:
    virtual void FactoryMethod();
};

//file .cpp
void ConcreteCreatorDipendente::FactoryMethod()
{
    Persone->Add(new ConcreteDipendente("Luigi", "Bross"));
    Persone->Add(new ConcreteDipendente("Toad", "Fungo"));
}

void ConcreteCreatorDatoreDiLavoro::FactoryMethod()
{
    Persone->Add(new ConcreteDatoreDiLavoro("Mario", "Boss"));
}
#Python
#Classe che si occupa di creare i dipendenti dell'azienda
class ConcreteCreatorDipendente(PersonaleAziendaCreator):

    def FactoryMethod(self):
        self.Persone.append(ConcreteDipendente("Luigi", "Bross"))
        self.Persone.append(ConcreteDipendente("Toad", "Fungo"))

#Classe che si occupa di creare i datori di lavoro dell'azienda
class ConcreteCreatorDatoreDiLavoro(PersonaleAziendaCreator):

    def FactoryMethod(self):
        self.Persone.append(ConcreteDatoreDiLavoro("Mario", "Boss"))
//Javascript
//Classe che si occupa di creare i dipendenti dell'azienda


Netrudy.Patterns._concreteCreatorDipendente = function Netrudy_Patterns__concreteCreatorDipendente() {
    Netrudy.Patterns._concreteCreatorDipendente.initializeBase(this);
}
Netrudy.Patterns._concreteCreatorDipendente.prototype = {
    
    factoryMethod: function Netrudy_Patterns__concreteCreatorDipendente$factoryMethod() {
        this.get_persone().add(new Netrudy.Patterns._concreteDipendente('Luigi', 'Bross'));
        this.get_persone().add(new Netrudy.Patterns._concreteDipendente('Toad', 'Fungo'));
    }
}

//Classe che si occupa di creare i datori di lavoro dell'azienda
Netrudy.Patterns._concreteCreatorDatoreDiLavoro = function Netrudy_Patterns__concreteCreatorDatoreDiLavoro() {
    Netrudy.Patterns._concreteCreatorDatoreDiLavoro.initializeBase(this);
}
Netrudy.Patterns._concreteCreatorDatoreDiLavoro.prototype = {
    
    factoryMethod: function Netrudy_Patterns__concreteCreatorDatoreDiLavoro$factoryMethod() {
        this.get_persone().add(new Netrudy.Patterns._concreteDatoreDiLavoro('Mario', 'Boss'));
    }
}
A questo punto proviamo il programma implementando il metodo main del nostro progetto:
//C#
//Istanzio la classe per creare i dipendenti
PersonaleAziendaCreator creaDipendenti = new ConcreteCreatorDipendente();
//Istanzio la classe per creare i datori di lavoro
PersonaleAziendaCreator creaDatori = new ConcreteCreatorDatoreDiLavoro();

//Unisco il gruppo di persone create
List persone = new List(creaDatori.Persone.Union(creaDipendenti.Persone));

//Per ogni persona scrive a video il tipo di oggetto 
//della persona e il nome
foreach (Persona persona in persone)
{
    Console.WriteLine("Persona (di tipo: {0}): {1}", persona.GetType(), persona.Nome);
}
'VB.NET
'Istanzio la classe per creare i dipendenti
Dim creaDipendenti As PersonaleAziendaCreator = New ConcreteCreatorDipendente()
'Istanzio la classe per creare i datori di lavoro
Dim creaDatori As PersonaleAziendaCreator = New ConcreteCreatorDatoreDiLavoro()

'Unisco il gruppo di persone create
Dim persone As New List(Of Persona)(creaDatori.Persone.Union(creaDipendenti.Persone))

'Per ogni persona scrive a video il tipo di oggetto della persona e il nome
For Each persona As Persona In persone
    Console.WriteLine("Persona (di tipo: {0}): {1}", persona.[GetType](), persona.Nome)
Next
//Java
//Istanzio la classe per creare i dipendenti
PersonaleAziendaCreator creaDipendenti = new ConcreteCreatorDipendente();
//Istanzio la classe per creare i datori di lavoro
PersonaleAziendaCreator creaDatori = new ConcreteCreatorDatoreDiLavoro();

//Unisco il gruppo di persone create
java.util.ArrayList<Persona> persone = new java.util.ArrayList<Persona>(creaDatori.getPersone().Union(creaDipendenti.getPersone()));

//Per ogni persona scrive a video il tipo di oggetto della persona e il nome
for (Persona persona : persone)
{
    System.out.println("Persona (di tipo: {0}): {1}", persona.getClass(), persona.getNome());
}
//C++/CLI file .cpp
//Istanzio la classe per creare i dipendenti
PersonaleAziendaCreator ^creaDipendenti = gcnew ConcreteCreatorDipendente();
//Istanzio la classe per creare i datori di lavoro
PersonaleAziendaCreator ^creaDatori = gcnew ConcreteCreatorDatoreDiLavoro();

//Unisco il gruppo di persone create
List<Persona^> ^persone = gcnew List<Persona^>(creaDatori->Persone->Union(creaDipendenti->Persone));

//Per ogni persona scrive a video il tipo di oggetto della persona e il nome
for each (Persona ^persona in persone)
{
    Console::WriteLine("Persona (di tipo: {0}): {1}", persona->GetType(), persona->Nome);
}
//C++ Nativo .cpp
//Istanzio la classe per creare i dipendenti
PersonaleAziendaCreator *creaDipendenti = new ConcreteCreatorDipendente();
//Istanzio la classe per creare i datori di lavoro
PersonaleAziendaCreator *creaDatori = new ConcreteCreatorDatoreDiLavoro();

//Unisco il gruppo di persone create
std::vector<Persona*> persone = std::vector<Persona*>(creaDatori->Persone->Union(creaDipendenti->Persone));

//Per ogni persona scrive a video il tipo di oggetto della persona e il nome
for (std::vector<Persona*>::const_iterator persona = persone.begin(); persona != persone.end(); ++persona)
{
    std::cout << "Persona (di tipo: " << (*persona)->GetType() << "): " << (*persona)->Nome << std::endl;
}
#Python
#Istanzio la classe per creare i dipendenti
creaDipendenti = ConcreteCreatorDipendente()
#Istanzio la classe per creare i i datori di lavoro
creaDatori = ConcreteCreatorDatoreDiLavoro()

#Unisco il gruppo di persone create
persone = list(set(creaDipendenti.getPersone()) | set(creaDatori.getPersone()))

#Per ogni persona scrive a video il tipo di oggetto della persona e il nome
for persona in persone:
    print "Persona (di tipo: {0})): {1}".format(type(persona), persona.Nome)
//Javascript
//Istanzio la classe per creare i dipendenti
var creaDipendenti = new Netrudy.Patterns._concreteCreatorDipendente();
//Istanzio la classe per creare i datori di lavoro
var creaDatori = new Netrudy.Patterns._concreteCreatorDatoreDiLavoro();
//Unisco il gruppo di persone create
var persone = creaDipendenti.get_persone().concat(creaDatori.get_persone());
//Per ogni persona scrive a video il tipo di oggetto della persona e il nome
var $enum1 = ss.IEnumerator.getEnumerator(persone);
while ($enum1.moveNext()) {
    var persona = $enum1.current;
    ss.Debug.writeln(String.format('Persona (di tipo: {0}): {1}', Type.getInstanceType(persona), persona.get_nome()));
}

lunedì 5 dicembre 2011

Libri gratis per programmatori

Qui, trovate i libri della rivista IO Programmo, degli ultimi 2,3 anni, formato PDF: “Libri di programmazione gratis”, c'è un po’di tutto per .NET, Java, C++, Python, SQL Server.


Conversione di un numero in colonna Excel

Ecco il codice per convertire un numero nell'indice alfanumerico di una colonna Excel:
public static class ExcelFunc
{
    public static string ConvertToLetter(int colIndex)
    {
        string ret = string.Empty;
        var alpha = colIndex/27;
        var remainder = colIndex-(alpha*26);
        if (alpha > 0)
            ret = Char.ConvertFromUtf32(alpha+64);
        if (remainder > 0)
                ret += Char.ConvertFromUtf32(remainder+64);
        return ret;
    }
}

Convertire un click in doubleclick

Utilzzando un controllo di terze parti, mi sono accorto che il suo produttore non aveva implementato l’evento double click in un punto che secondo me era essenziale, allora con qualche riga di codice mi sono trasformato un evento click in double click:
private DateTime mTimeToDoubleC = DateTime.Now;

private void button1_Click(object sender, EventArgs e)
{
    DateTime adesso = DateTime.Now;
    if ((adesso - mTimeToDoubleC) < new TimeSpan(0, 0, 0, 0, SystemInformation.DoubleClickTime))
    {
        //Esegui il metodo per il double click...
    }
    else
    {
        //Esegui il metodo per il click normale...
    }
}
Come si può vedere utilizzando la proprietà SystemInformation.DoubleClickTime ottengo un double click perciso come impostato nel sistema.

Evento minimize e forms ridotti a icona nella Tray

Ecco il codice per gestire una form che passa dalla visualizzazione normale alla tray bar e dopo avere fatto doppio click sull’icona ritorna alla posizione iniziale in primo piano:

Come prima cosa aggiungiamo a design il componente “NotifyIcon” e lo chiamiamo “notifyIcon”.
Impostiamo la proprietà visible a false.
Siccome non abbiamo un evento minimized, implementiamo il seguente codice usando l’evento Resize della form:
private void FrmMain_Resize(object sender, EventArgs e)
{
    if (System.Windows.Forms.FormWindowState.Minimized == WindowState)
    {
        this.Hide();
        notifyIcon.Visible = true;
    }
}
Ora implementiamo il seguente codice per l’evento DoubleClick sulla notifyIcon e il gioco è fatto:
private void notifyIcon_DoubleClick(object sender, EventArgs e)
{
    this.Show();
    this.WindowState = FormWindowState.Normal;
    notifyIcon.Visible = false;
}

Localizzare i mesi dell'anno

Per ottenere i nomi dei mesi dell'anno localizzati in base alla lingua corrente del vostro programma potete usare questa semplice funzione:
//C#
int iMonth = 1; //Numero intero che corrisponde al mese da localizzare (in questo caso Gennaio)
string month = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(iMonth);
'VB.NET
Dim iMonth As Integer = 1
'Numero intero che corrisponde al mese da localizzare (in questo caso Gennaio)
Dim month As String = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(iMonth)

venerdì 2 dicembre 2011

Impedire l'esecuzione del programma .NET ad un utente che non sia amministratore

Un esigenza molto comune per esempio, se si vuole fare una console di amministazione di un servizio è quella che un applicazione o un metodo siano eseguiti solo se l'utente appartiene ad un determinato gruppo che ha i permessi necessari, per esempio ad accedere ad una determinata risorsa. Nel seguente esempio scritto in C# se l'utente che esegue il thread non è un amministratore allora il metodo genera un eccezione e si può chiudere l'applicazione.

Come prima cosa bisogna applicare i criteri principali del dominio applicazione corrente a WindowsPrincipal, altrimenti una richiesta di autorizzazione principale avrà esito negativo.
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
Ora abbiamo bisogno di sapere quale è l'utente che sta eseguendo il thread corrente.
//Estrae l'identità dell'utente del thread corrente
WindowsIdentity wi = (WindowsIdentity)System.Threading.Thread.CurrentPrincipal.Identity;
                
//Estrae il nome utente da suo sid
IdentityReference mYaccount = wi.User.Translate(typeof(NTAccount));
//Visualizza il nome utente estratto da suo sid
MessageBox.Show("Utente:" + mYaccount.Value);
Adesso dobbiamo ricavare il gruppo administrator da assegnare alla funzione di controllo. Per aiutarvi potete visualizzare i nomi dei gruppi a cui l'utente del thread appartiene così:
StringBuilder sbMsg = new StringBuilder();
foreach (IdentityReference sidRef in wi.Groups)
{
    IdentityReference account = sidRef.Translate(typeof(NTAccount));
    sbMsg.AppendLine(account.Value);
}
MessageBox.Show(sbMsg.ToString());
Ora per impedire all'applicazione di partire se non siamo amministratori, usiamo le seguenti istruzioni:
try
{
    PrincipalPermission permessi = 
        new PrincipalPermission(mYaccount.Value, "BUILTIN\\Administrators");
                
    permessi.Demand();
}
catch (SecurityException ex)
{
   MessageBox.Show(ex);
   //Esci dall'applicazione
}

Comprimere e decomprimere con .Net 2.0

Ecco come usare gli oggetti per la compressione messi a disposizione dal Framework .NET 2.0
//C#
using System.IO;
using System.IO.Compression;


public static class Compressor
{
 public static byte[] Compress(byte[] data)
 {
  MemoryStream output = new MemoryStream();
  GZipStream gzip = new GZipStream(output, CompressionMode.Compress, true);
  gzip.Write(data, 0, data.Length);
  gzip.Close();
  return output.ToArray();
 }


 public static byte[] Decompress(byte[] data)
 {
  MemoryStream input = new MemoryStream();
  input.Write(data, 0, data.Length);
  input.Position = 0;
  GZipStream gzip = new GZipStream(input, CompressionMode.Decompress, true);
  MemoryStream output = new MemoryStream();
  byte[] buff = new byte[64];
  int read = -1;
  read = gzip.Read(buff, 0, buff.Length);
  

  while (read > 0)
  {
   output.Write(buff, 0, read);
   read = gzip.Read(buff, 0, buff.Length);
  }
  

  gzip.Close();
  return output.ToArray();
 }
}
'VB
Imports System.IO
Imports System.IO.Compression


Public Class Compressor


 Public Shared Function Compress(ByVal data As Byte()) As Byte()
  Dim output As MemoryStream = New MemoryStream
  Dim gzip As GZipStream = New GZipStream(output, CompressionMode.Compress, True)
  gzip.Write(data, 0, data.Length)
  gzip.Close()
  Return output.ToArray
 End Function


 Public Shared Function Decompress(ByVal data As Byte()) As Byte()
  Dim input As MemoryStream = New MemoryStream
  input.Write(data, 0, data.Length)
  input.Position = 0
  Dim gzip As GZipStream = New GZipStream(input, CompressionMode.Decompress, True)
  Dim output As MemoryStream = New MemoryStream
  Dim buff(64) As Byte
  Dim read As Integer = -1
  read = gzip.Read(buff, 0, buff.Length)


  While read > 0
   output.Write(buff, 0, read)
   read = gzip.Read(buff, 0, buff.Length)
  End While


  gzip.Close()
  Return output.ToArray
 End Function


End Class

Icone dei componenti nella Toolbox .NET

Per aggiungere un icona ad un nuovo componente creato con Visual Studio in modo che si veda nella toolbox si può usare uno dei seguenti metodi:
//C#
//Specifica la bitmap associata al tipo Button.
[ToolboxBitmap(typeof(Button))]
class MyControl1 : UserControl
{
}


//Specifica un bitmap file.
[ToolboxBitmap(@"C:\Documents and Settings\Rudy\Documenti\Immagini\myImage.bmp")]
class MyControl2 : UserControl
{
}


//Specifica un tipo che indica l'assembly in cui cercare e il nome del immagine nelle risorse.
[ToolboxBitmap(typeof(MyControl), "MioControlloBitmap")]
class MyControl : UserControl
{
}
'VB
'Specifica la bitmap associata al tipo Button.
 _
Class MyControl1
    Inherits UserControl
End Class


'Specifica un bitmap file.
 _
Class MyControl2
    Inherits UserControl
End Class


'Specifica un tipo che indica l'assembly in cui cercare e il nome del immagine nelle risorse.
 _
Class MyControl
    Inherits UserControl
End Class
Va ricordato che l'immagine deve essere una bitmap a 16x16 o 32x32, inoltre se usate il primo metodo l'immagine nelle risorse deve chiamarsi "Namespace.NomeClasse.bmp" mentre se usate l'ultimo "Namespace.MioControlloBitmap"

Percorso del file eseguibile di un programma .NET

Per ottenere il percorso del file eseguibile da cui è partita l'applicazione, il namespace System.Windows.Forms ci mette a disposizione il metodo statico Application.StartupPath.
Tuttavia se non vogliamo o non possiamo referenziare System.Windows.Forms, ad esempio, per ottenere il percorso in funzione di una dll referenziata nel progetto, allora possiamo usare il seguente metodo:
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
Prestate molta attenzione se volete aprire un file che si trova nella stessa cartella dell'eseguibile, è buona norma che passiate al metodo il percorso e il nome del file Es.: File.Open(@"C:\Progetti\MiaApplicazione\test.txt"). Se usate solamente il nome file Es.: File.Open(@"test.txt") e per caso in precedenza avete usato una OpenFileDialog o SaveFileDialog per aprire o salvare un file il percorso in cui verrà cercato il vostro file text.txt sarà equivalente all'ultimo selezionato tramite questi controlli.

P.S: anche System.Environment.CurrentDirectory soffre dello stesso problema.

Lettura e scrittura con MemoryStream .NET

Poichè ogni volta che devo usare un MemoryStream devo sempre ricordarmi come funzionano gli stream e le operazioni di lettura e scrittura meglio postare questo pezzetto di codice che può essere utile:
//C#
System.IO.MemoryStream ms = new System.IO.MemoryStream();
Byte[] by = System.Text.Encoding.UTF8.GetBytes("Mio testo");
ms.Write(by, 0, by.Length);
ms.Position = 0;
Byte[] buffer = new byte[by.Length];
ms.Read(buffer, 0, buffer.Length);
string sTesto = System.Text.Encoding.UTF8.GetString(buffer);
'VB
Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream
Dim by As Byte() = System.Text.Encoding.UTF8.GetBytes("Mio testo")
ms.Write(by, 0, by.Length)
ms.Position = 0
Dim buffer(by.Length) As Byte
ms.Read(buffer, 0, buffer.Length)
Dim sTesto As String = System.Text.Encoding.UTF8.GetString(buffer)

Singola istanza di un applicazione C#

Per essere sicuri si eseguire una singola istanza di un applicazione C# potete scrivere il seguente codice:
//C#
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;

namespace ProvaCSharp
{
 static class Program
 {
  private static Mutex mutex;

  ///
  /// The main entry point for the application.
  /// 
  [STAThread]
  static void Main()
  {
   mutex = new Mutex( true, Application.ProductName );
   if (mutex.WaitOne(0, false))
   {
    Application.Run(new Form1());
   }
   else
   {
    MessageBox.Show(Application.ProductName + " è già in esecuzione");
   }
  }
 }
}

Modificare lo stato di un controllo da un operazione asincrona .NET

Quante volte avete avuto la necessità di aggiornare un controllo che si trova su una form istanziata dal thread principale dell'applicazione, da un altro thread che sta seguendo un operazione asincrona? Ecco come evitare errori di cross thread e non duplicare il codice:
//C#
private delegate void InvokeMiaFunzione();
private InvokeMiaFunzione mInvokeMiaFunzione;

private void MiaFunzione()
{
 if (this.InvokeRequired)
 {
  this.Invoke(mInvokeMiaFunzione);
 }
 else
 {
  // Qui si può modificare lo stato del controllo della form senza incorrere in nessun problema
 }
}

private void CostruttoreDellaClasse()
{
 mInvokeMiaFunzione = new InvokeMiaFunzione(MiaFunzione);
}

//Chiamata da un processo asincrono
private void ProcessoAsincrono()
{
 MiaFunzione();
}

//Chiamata da un processo sincrono
private void ProcessoSincrono()
{
 MiaFunzione();
}
'VB
Private Delegate Sub InvokeMiaFunzione()
Private mInvokeMiaFunzione As InvokeMiaFunzione

Private Sub MiaFunzione()
    If Me.InvokeRequired Then
        Me.Invoke(mInvokeMiaFunzione)
    Else
        'Qui si può modificare lo stato del controllo della form senza incorrere in nessun problema
    End If
End Sub

Private Sub CostruttoreDellaClasse()
    mInvokeMiaFunzione = AddressOf MiaFunzione
End Sub

'Chiamata da un processo asincrono
Private Sub ProcessoAsincrono()
    MiaFunzione()
End Sub

'Chiamata da un processo sincrono
Private Sub ProcessoSincrono()
    MiaFunzione()
End Sub

I files di configurazione di un applicazione .NET

Segnalo questo link, al mio primo articolo, relativo ai files di configurazione delle applicazioni .NET, è stato scritto qualche anno fa, ma a oggi è ancora valido.

giovedì 1 dicembre 2011

Ottenere l'IP reale anche con un proxy

RealIP = Request.ServerVariables["REMOTE_ADDR"].ToString();
ClientIP = Request.ServerVariables["HTTP_CLIENT-IP"];

if(ClientIP!="")
{
    RealIP = ClientIP;
}
else
{
    Forwarded = Request.ServerVariables["HTTP_X_Forwarded-For"];
}

if (Forwarded != "")
    RealIP = Forwaded;