My Blog

System.Reflection.Emit: Creare un metodo "al volo" ed invocarlo

by lupok on giovedì 24 gennaio 2013 12:36

Abbiamo a disposizione una classe con un metodo che legge un file e ne ritorna il contenuto, quindi dobbiamo creare un metodo "al volo" che: 

1) crea un'istanza della classe,
2) chiama il metodo di lettura del file,
3) stampa a video il contenuto del file.

Per prima cosa occorre creare un nuovo progetto di tipo "Console Application" quindi aggiungiamo una nuova classe:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace CreateAndCallMethodRuntime
{
   class MyClass
   {
      public String ReadFile(String path)
      {
         return System.IO.File.OpenText(path).ReadToEnd();
      }
   }
}
Nella classe MyClass abbiamo aggiunto un metodo che legge il file passato per parametro e ne ritorna il contenuto sotto forma di stringa. 

Di seguito è presente il codice necessario per implemtare la procedura descritta sopra:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
 
namespace CreateAndCallMethodRuntime
{
   class Program
   {
      static void Main(string[] args)
      {
         // dichiarazione del metodo in cui si specifica il nome, 
         // il tipo di ritorno, i parametri la classe a cui è associato
         DynamicMethod print = new DynamicMethod("Print"null, 
            new Type[] { typeof(String) }, typeof(MyClass));
 
         //Ottiene un generatore di MISL per il metodo Print
         ILGenerator il = print.GetILGenerator(256);
 
         //definisce un parametro per il metodo Print
         print.DefineParameter(1, ParameterAttributes.In, "path");
 
         //crea una nuova istanza della classe MyClass
         il.Emit(OpCodes.Newobj, typeof(MyClass).GetConstructor(new Type[0]));
 
         //carica il parametro 0 del metodo Print
         il.Emit(OpCodes.Ldarg_0);
 
         //chiama il metodo readFile della class MyClass con paramtro 0
         il.Emit(OpCodes.Callvirt, typeof(MyClass).GetMethod("ReadFile"));
 
         //stampa il valore di ritorno ricevuta dall'invocazione di readFile
         il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine"new[] { typeof(String) }));
 
         il.Emit(OpCodes.Ret);
 
         //invoca il metodo dinamico Print con il percorso del file da stampare
         print.Invoke(new MyClass(), new Object[] { "TextFile1.txt" });
 
      }
   }
}
CreateAndCallMethodRuntime.zip

Blogs Parent Separator My Blog
Author
lupok

My Blog

Tags