Create delegate using ILGenerator

646 views Asked by At

How can I dynamically create a delegate with an unknown MethodInfo called on an unknown target with unknown arguments using ILGenerator.Emit (not LambdaExpression.Compile? Because I'm trying to find a more performant solution)

public void CreateDelegate(MethodInfo mi, object target, object[] arguments)
{
    var method = new DynamicMethod("Temp", typeof(void), Type.EmptyTypes);
    var generator = method.GetILGenerator();
    // Make the method call mi on target with arguments
    // ...
    method.CreateDelegate(typeof(Action));
}
1

There are 1 answers

0
Konard On

Maybe you are looking something like this? If by Unknown you mean Any:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;

namespace Platform.Reflection
{
    public static class DelegateHelpers
    {
        public static TDelegate CompileOrDefault<TDelegate>(Action<ILGenerator> emitCode)
            where TDelegate : Delegate
        {
            var @delegate = default(TDelegate);
            try
            {
                var delegateType = typeof(TDelegate);
                var invoke = delegateType.GetMethod("Invoke");
                var returnType = invoke.ReturnType;
                var parameterTypes = invoke.GetParameters().Select(s => s.ParameterType).ToArray();
                var dynamicMethod = new DynamicMethod(Guid.NewGuid().ToString(), returnType, parameterTypes);
                var generator = dynamicMethod.GetILGenerator();
                emitCode(generator);
                @delegate = (TDelegate)dynamicMethod.CreateDelegate(delegateType);
            }
            catch (Exception exception)
            {
                // ignore
            }
            return @delegate;
        }
    }
}

Or, you can just reference Platform.Reflection (version 0.1.0 or later) NuGet package. And use Platform.Reflection.DelegateHelpers.