vines
vines

Reputation: 5225

Need a method to obtain code that would construct a given expression tree

There are two ways to construct an expression tree in C#:

  1. let the compiler rewrite a lambda and store the result;
  2. construct it piecewise, calling factory methods provided by the Expression class.

The first approach is simple, but it doesn't let me integrate already existing subexpressions into a resulting expression, which is my main goal. (These subs are passed to me as function parameters by design).

In fact, the second approach itself is the subexpression composition process, but it is very cumbersome for anything but the simplest expressions with little to no nesting involved.

So, to get the best of two ways, while having to construct the trees piecewise, I look at copiler-generated expressions, and use them as hints. What I do is: write the code to construct a tree, while looking at the given tree. The whole process is quite a routine, so I wonder:

Here's the explaination of why I need this strange process at all.

Expression<Func<IEnumerable<N>, IEnumerable<N>, IEnumerable<N>>>
    MyExpression = (src1, src2) => 
        src1.SelectMany(outer => lookup[outer.Value1].Select(
                inner => new N(outer, inner)));

Now, I am provided with two subexpressions, which are to be placed instead of outer.Value1 and new N(outer, inner). I can't use .Compile() and utilise them as lambdas, because I have to provide the complete expression tree for further processing intact. I need a way to integrate them into MyExpression, and the only method I'm aware of is to construct the whole tree via Expression factories. But with more complex queries it gets extremely complex and error-prone.

Upvotes: 3

Views: 91

Answers (1)

StriplingWarrior
StriplingWarrior

Reputation: 156728

aside from codegens, are there some other possibilities to improve my method and make it more productive?

Basically you'd want to write a class that extends ExpressionVisitor that replaces some component of one expression with pieces from the other expression.

are there tools to automate that?

LINQKit does just that. From the website's examples:

Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000;
Expression<Func<Purchase,bool>> criteria2 = p => criteria1.Invoke (p)
                                             || p.Description.Contains ("a");

Console.WriteLine (criteria2.Expand().ToString());

Output:

p => ((p.Price > 1000) || p.Description.Contains("a"))

Upvotes: 2

Related Questions