score:3

Accepted answer

I don't believe this is currently possible to do with the compiler's help (as of C# 4.0), but you could of course do it "by hand" with Expression.Invoke.

Creates an InvocationExpression that applies a delegate or lambda expression to a list of argument expressions.

In your case, this would look something like:

Expression<Func<int, int>> f = x => x + x;

var parameter = Expression.Parameter(typeof(int),"y");
var body = Expression.Add(Expression.Constant(2), Expression.Invoke(f, parameter));

// Loosely speaking: y => 2 + f(y)
var g = Expression.Lambda<Func<int, int>>(body, parameter);

LINQKit provides the Invoke /Expand extension-methods that do the leg-work for you, giving you back the ability to use lambdas for this. This will let you do:

Expression<Func<int, int>> f = x => x + x;
Expression<Func<int, int>> g = x => 2 + f.Invoke(x);

// Note: 'Inlines' the invocation into the target expression.
var finalExpression = g.Expand();

..which is very close to the syntax you had originally wanted.

One point to note about InvocationExpressions is that some LINQ providers (such as LINQ to Entities) don't like them at all; so you'll have often have to 'expand' out the invoked expression so that it looks like one single expression to the provider. You can of course do this by hand, but LINQKit again comes in handy with the AsExpandable extension.


Related Articles