Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a delegate for a reflected method at run time

I want to create a Delegate of a reflected method, but the Delegate.CreateDelegate requires the Type of delegate be specified. Is it possible to dynamically create a 'Delegate' that matches whatever function is reflected?

Here is a simple example:

class Functions
{
    public Functions()
    {

    }

    public double GPZeroParam()
    {
        return 0.0;
    }

    public double GPOneParam(double paramOne)
    {
        return paramOne;
    }

    public double GPTwoParam(double paramOne, double paramTwo)
    {
        return paramOne+paramTwo;
    }
}

static void Main(string[] args)
{
    Dictionary<int, List<Delegate>> reflectedDelegates = new Dictionary<int, List<Delegate>>();
    Functions fn = new Functions();
    Type typeFn = fn.GetType();
    MethodInfo[] methods = typeFn.GetMethods();

    foreach (MethodInfo method in methods)
    {
        if (method.Name.StartsWith("GP"))
        {
            ParameterInfo[] pi = method.GetParameters();

            if (!reflectedDelegates.ContainsKey(pi.Length))
            {
                reflectedDelegates.Add(pi.Length, new List<Delegate>());
            }

            // How can I define a delegate type for the reflected method at run time?
            Delegate dlg = Delegate.CreateDelegate(typeof(???), fn, method);
            reflectedDelegates[pi.Length].Add(dlg);
        }
    }
}

Update:

The closest thing I found is this FastInvokeWrapper on code-project, but I'm still trying to wrap my head around it and I don't quite understand how GetMethodInvoker binds the reflected method to the FastInvokeHandler.

like image 993
Kiril Avatar asked Nov 15 '22 09:11

Kiril


1 Answers

The whole point of this type of delegate-reflection optmization is that you know what type of delegate you need at the compile time. If you cast it to type Delegate like this Delegate dlg = you will have to invoke it with Invoke method which is the same reflection.

So you should use IL generation or Expression Trees instead to generate neutral delegates like Func<object,object[],object>.

Also read this for better understanding.

like image 98
Vlad Avatar answered Dec 21 '22 13:12

Vlad