ads

Le novità di C# 4.0

Maggio 12th, 2009 No Comments   Posted in In rilievo, Programmazione

Il nuovo Microsoft .Net Framework 4.0 è arrivato ad uno stato avanzato di sviluppo. Forse per fine anno o metà del prossimo potremmo beneficiare non solo di una moltitudine di nuove funzionalità del .net framework ma anche del nuovo Visual Studio 2010 realizzato interamente in WPF.

In questo articolo ci concentreremo esclusivamente sulle novità apportate al linguaggio C# 4.0. Molte delle novità descritte in questo articolo sono già testabili scaricando e installando la Microsoft Pre-release Software Visual Studio 2010 and .NET Framework 4.0 Community Technology Preview. Si tratta di una macchina Virtual PC con dentro Windows, Visual Studio 2010 e il .net framework già installati e configurati. Per un totale di circa 7GB di macchina virtuale!

Complessivamente le novità introdotte in C# 4.0 si possono riassumere nel seguente elenco:

  1. Dynamic Type Object
  2. Name e Optional Arguments
  3. Co-variance e Contra-variance
  4. Migliorie su COM Interop

Vediamo in dettaglio.

Dynamic Type Object

Il Dynamic Type Object è un nuovo tipo statico introdotto soprattutto a beneficio del Dynamic Language Runtime (DLR). Con la nuova parola chiave dynamic è possibile dichiarare un type che verrà risolto solo a run-time. In questo modo:

public void MyFunction()
{
    // le seguenti variabili verranno convertite
    // implicitamente a run-time. 
    dynamic counter = 1;
    dynamic hello = "Hello C# 4.0";
}

Su un type dichiarato come dynamic è possibile richiamare metodi, campi o proprietà, come se fosse un object. Il tutto verrà risolto automaticamente a run-time in base al type effettivo contenuto all’interno della variabile. Con questa parola chiave C# 4.0 si uniforma così ai tipici linguaggi dinamici (dynamic appunto) come Ruby o Php.

Name e Optional Arguments

L’optional argument è una funzionalità del linguaggio già presente in Visual Basic ed è la capacità di dichiarare come opzionale un parametro di un metodo, in questo modo:

// il parametro i risulta essere obbligatorio
// mentre il parametro y è optionale e per
// default viene impostato a 0.
public int Calc(int i, int y = 0)
{
    // corpo del metodo
}

public void Main()
{
    // ho la possibilità di richiamare Calc con un
    // solo parametro o con due, poiché il parametro
    // y risulta essere opzionale.
    int result1 = Calc(5); // equivalente a Calc(5, 0);
    int result2 = Calc(10, 3)
}

Il name argument invece è la facoltà di passare un parametro per nome, in questo modo:

public int Calc(int i, int y = 0, int z = 1)
{
    // corpo del metodo
}

public void Main()
{
    // In questo modo chiamo il metodo Calc con i parametri
    // invertiti, cioè prima passando y e poi x.
    int result = Calc(y: 3, i: 4); // equivalente a Calc(4, 3, 0);

    // In questo, invece chiamo Calc passando i e z ma non y
    int result2 = Calc(z: 6, i: 3); // equivalente a Calc(3, 0, 6);
}

Co-variance e Contra-variance

Introduciamo il concetto di covarianza e contravarianza. Date due classi A e B. Dove B è una sotto classe di A, e avente una nuova classe C si dice che C è covariante rispetto a T se anche C è una sotto classe di C. Mentre si dice che C è contravariante rispetto a T se anche C è super classe di C. In pratica:

Questo risulta particolarmente interessante con i type parameter dei generics. In questo modo potremmo, per esempio, assegnare una collection di stringhe ad una collection di oggetti, dato che la classe string e sotto classe di object, o vice versa, così:

IList<string> strings = new List<string>();
IList<object> objects = strings;

I benefici della covarianza e della contravarianza non si limitano a questo aspetto, ma come esempio è chiarificatore.

Migliorie su Com Interop

Tra le migliorie su Com Interop citiamo:

  • Importazione dinamica con l’utilizzo del Dynamic Type Object invece che object
  • Compilazione senza PIA (Primary Interop Assemblies) che rendevano pensante l’applicazione
  • Chiamate a metodi senza l’utilizzo di ref

Conclusioni

Che dire, le novità sono davvero tante e tutte decisamente interessanti. Prima tra tutte la citata parolina magica dynamic, che introduce una vera e propria rivoluzione per un linguaggio prettamente statico come C#. Non resta che aspettare l’uscita ufficiale sia del .Net Framework 4.0 ma soprattutto del nuovissimo Visual Studio 2010 che merita veramente la visione, ma questa è un‘altra storia. 🙂

Risorse

Alcune risorse utili:

Ti piace questo articolo? Condividilo:

Diminuire l’effetto flickering aumentando le prestazioni in GDI+

Marzo 12th, 2009 2 Comments   Posted in Programmazione

Quando si iniziare ad utilizzare GDI+ nel .NET Framework il primo problema da affrontare è il così detto effetto flickering. Il flickering è quel fastidioso sfarfallio che vediamo quando disegniamo un oggetto in GDI+, come un rettangolo o un cerchio.

Esistono numerosi trucchetti per togliere, almeno parzialmente, questo problema e contemporaneamente aumentare le prestazioni grafiche. Il primo consiglio è quello di impostare la proprietà DoubleBuffer della Windows Form a True. Anche se il consumo di memoria aumenterà le prestazioni ne beneficeranno. Inoltre è bene impostare altre proprietà interessanti. Possiamo fare tutto in un colpo solo impostando un’insieme di stili nel costruttore della windows form. In questo modo:

   1: public Form1()
   2: {
   3:     this.InitializeComponent();
   4:
   5:     this.SetStyle(ControlStyles.UserPaint, true);
   6:     this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
   7:     this.SetStyle(ControlStyles.DoubleBuffer, true);
   8:     this.SetStyle(ControlStyles.ResizeRedraw, true);
   9:     this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
  10:     this.UpdateStyles();
  11: }

Questo sistema dovrebbe bastare per ridurre notevolmente il flickering. Ma se volete spingere al massimo le prestazioni c’è ancora una cosa che si può fare: utilizzare un’immagine bitmap come buffer ulteriore. In questo modo gli oggetti vengono prima disegnati sulla bitmap di buffer e successivamente la bitmap viene a sua volta renderizzata sulla form. In questo modo:

   1: private void Form1_Paint(object sender, PaintEventArgs e)
   2: {
   3:     // Creo una bitmap in memoria.
   4:     Bitmap buffer = new Bitmap(this.Width, this.Height);
   5:
   6:     // Utilizzo l'oggetto Graphics della bitmap
   7:     // e disegno tutti i miei oggetti.
   8:     using (Graphics graphics = Graphics.FromImage(buffer))
   9:     {
  10:         // disegno tutti i miei oggetti.
  11:     }
  12:
  13:     // Pulisco la superficie della form e disegno
  14:     // l'immagine che ho in memoria.
  15:     e.Graphics.Clear(this.BackColor);
  16:     e.Graphics.DrawImage(buffer, 0, 0, buffer.Width, buffer.Height);
  17: }

Le prestazioni sono garantite. 🙂

Ti piace questo articolo? Condividilo: