So I have a
delegate which points to some function which I don't actually know about when I first create the
delegate object. The object is set to some function later.
I also then want to make an expression tree that invokes the delegate with an argument (for this question's sake the argument can be
5). This is the bit I'm struggling with; the code below shows what I want but it doesn't compile.
Func<int, int> func = null; Expression expr = Expression.Invoke(func, Expression.Constant(5));
For this example I could do (this is practical since I need to build the expression trees at runtime):
Func<int, int> func = null; Expression<Func<int>> expr = () => func(5);
() => Invoke(value(Test.Program+<>c__DisplayClass0).func, 5)
Which seems to mean that to use the
func, I need to produce the
So, how can I make an expression tree which invokes a delegate?
OK, this shows how it can be done (but it is very inelegant in my opinion):
Func<int, int> func = null; Expression<Func<int, int>> bind = (x) => func(x); Expression expr = Expression.Invoke(bind, Expression.Constant(5)); Expression<Func<int>> lambda = Expression.Lambda<Func<int>>(expr); Func<int> compiled = lambda.Compile(); Console.WriteLine(expr); func = x => 3 * x; Console.WriteLine(compiled()); func = x => 7 * x; Console.WriteLine(compiled()); Console.Read();
Essentially I use
(x) => func(x); to make a function that calls what the delegate points to. But you can see that
expr is overly complicated. For this reason I don't consider this answer good, but maybe it can be built upon?
I think what you want to do is use the Target and Method properties of the delegate to pass to create a Call expression. Building on JulianR's sample, this is what it would look like:
Action<int> func = i => Console.WriteLine(i * i); var callExpr = Expression.Call(Expression.Constant(func.Target), func.Method, Expression.Constant(5)); var lambdaExpr = Expression.Lambda<Action>(callExpr); var fn = lambdaExpr.Compile(); fn(); // Prints 25