Call Func<> with argument of type object

c# expression-trees func

Question

I have (for instance) a Func<int, int> which I want to call as usual, except that the parameter is of type object rater than int. I only know the exact type of the Func and the argument at runtime, because the Func was created using Expression trees and is now accessed from a dynamic variable. (Simplified) code example:

using System.Linq.Expressions;

namespace FuncExample
{
    class Program
    {
        static void Main(string[] args)
        {
            object myFunc = CreateFunc(); // Could return something like
                                          // Func<int, int>, but may return a
                                          // completely different Func<> depending on
                                          // arguments etc.
            object result = getFromFunc(5, myFunc);
        }

        public static object CreateFunc()
        {
            LambdaExpression expr = Expression.Lambda(
                /*
                 * Create an expression
                 */
                );
            return expr.Compile();
        }

        public static object getFromFunc(object arg, object func)
        {
            dynamic dynFunc = func;
            return dynFunc(arg); // <------- Throws exception
        }
    }
}

How can I make the code convert arg into an integer or whatever Type the argument is? I tried making a generic method that casts the object to a certain type and then invoking it through reflection like this:

public static T asT<T>(object n)
{
    return (T)n;
}

for getFromFunc:

MethodInfo con = typeof(Program).GetMethod("asT").MakeGenericMethod(func.GetType().GetGenericArguments()[0]);
return dfunc(con.Invoke(null, new[] { value }));

But MethodInfo.Invoke also returns object. Any ideas on how to make sure the argument has the correct type?

Accepted Answer

You're already using dynamic, so why not use dynamic?

return dynFunc((dynamic)arg);

This makes sure arg's runtime type gets used for determining whether it's an appropriate argument.


Popular Answer

All delegates derive from System.Delegate. You can use the System.Delegate.DynamicInvoke method to call a delegate whose type you don't know at compile time, similar to calling a method using MethodInfo.Invoke(). For example:

class Program
{
    public static Delegate CreateFunc()
    {
      return new Func<int, int>(x => x + 1);
    }

    public static void Main(string[] args)
    {
        var func = CreateFunc();
        object inArg = 42;
        object result = func.DynamicInvoke(inArg);
        Console.WriteLine(result);
    }
}


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why