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?

1
0
5/9/2013 7:45:04 PM

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.

2
5/9/2013 7:51:40 PM

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);
    }
}


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow