Reflection mediante dynamic
Al Supporto Tecnico ci prepariamo in anticipo alle richieste sui prodotti attualmente in beta, i quali arriveranno nei prossimi mesi. Studiando Visual C# 2010 Beta 1 e le nuove feature introdotte nella runtime, ho notato che gli sviluppatori di applicazioni hanno a disposizione un nuova keyword, dynamic, che si basa sulla DLR, Dynamic Language Runtime.
Per la definizione formale e per come il compilatore si comporta durante la fase di compile-time vi rimando alla documentazione on-line che sicuramente esprime questi concetti teorici in modo più chiaro di quanto possa fare io.
Quel che m’interessa descrivere è l’impatto che questo nuovo costrutto ha sulla Reflection, in particolare su come si sia notevolmente semplificata la scrittura del codice. A tal fine ripercorriamo rapidamente come funzionava la reflection sino alla versione 3.5 della runtime.
Uno sviluppatore doveva interagire con la DLL che definisce il tipo interessato e successivamente invocare le funzioni implementate nella classe tramite InvokeMember. Questo rendeva la stesura del codice sicuramente più articolata di una normale invocazione di funzione, costringendo lo sviluppatore a distinguere tra le istanze realizzate mediante Reflection e le istanze “tradizionali”.
Vediamo di seguito il seguente codice che definisce la libreria ClassLibrary:
namespace ClassLibrary
{
public class MyMath
{
public long sum(int x, int y)
{
return x + y;
}
}
}
Ecco cosa accadeva nelle vecchie edizioni della runtime:
class Program
{
static void Main(string[] args)
{
Assembly myLibrary = null;
try
{
// Carico la Libreria interessata
myLibrary = Assembly.LoadFrom("C:\\ClassLibrary.dll");
// Reperisco la classe con cui interagire
Type MyMathType = myLibrary.GetType("ClassLibrary.MyMath");
// Creo un'istanza della classe tramite reflection
Object MyMathObj = Activator.CreateInstance(MyMathType);
// Preparo gli argomenti da passare alla funzione
Object[] methodArgs = new Object[2];
methodArgs[0] = 2;
methodArgs[1] = 3;
// Invoco il metodo sum indicando l'istanza, i parametri in ingresso ed i flag opportuni
Console.WriteLine("The sum of 3 + 2 is " +
MyMathType.InvokeMember("sum", BindingFlags.Default | BindingFlags.InvokeMethod,
null, MyMathObj, methodArgs).ToString());
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
Console.ReadLine();
}
}
Con i tipi dynamic la stesura di codice mediante la tecnica della reflection è praticamente identica all’invocazione di un metodo per una normale istanza:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//Carico la dll interessata definendo un’istanza
dynamic test = Assembly.LoadFrom("C:\\ClassLibrary.dll").CreateInstance("ClassLibrary.MyMath");
// invoco il metodo tramite reflection, in modo del tutto trasperante
Console.WriteLine("La somma di 3+2 =" + test.sum(3, 2));
Console.ReadLine();
}
}
}
Non ci siamo notevolmente semplificati la vita?
Support Engineer
Windows Mobile & Embedded Developer Support
.NET & Visual Studio Technology