Llamar a un System.Action en un método dinámico de .NET.
Tengo una función que está construyendo un método dinámico. Como parte de este método dinámico, está llamando a una acción conocida en el momento de la generación. Como ejemplo mínimo y reproducible, considera el siguiente código C#:
using System.Reflection.Emit;
static class Program {
static Action MakeAction(Action action) {
DynamicMethod method = new DynamicMethod("test", null, null);
ILGenerator generator = method.GetILGenerator();
generator.Emit(OpCodes.Call, action.Method);
generator.Emit(OpCodes.Ret);
return method.CreateDelegate<action>();
}
static void Main() {
MakeAction(() => Console.WriteLine("Hello"))();
}
}
Cuando ejecuto esto, obtengo una System.InvalidProgramException. ¿Cuál es la forma correcta de hacer esto?
davy.ai
El problema con el código proporcionado es que el método
MakeAction
está intentando emitir una instrucción de llamada al métodoaction.Method
, que no es un método virtual y, por lo tanto, no puede ser llamado dinámicamente. Para solucionar esto, puedes usar la APIExpression
para crear un delegado a partir del parámetroaction
y luego emitir una instrucción de llamada al delegado creado en su lugar. Aquí tienes una versión actualizada del código:Con este cambio, la salida debería ser “hello”, como se espera.