3

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:

  • are there tools to automate that? Couldn't find any myself.
  • aside from codegens, are there some other possibilities to improve my method and make it more productive?

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.

vines
  • 5,160
  • 1
  • 27
  • 49
  • I don’t understand your question. You want something that converts lambda expressions into code that creates expressions? Why? Give an actual example of what you’re trying to solve please. – poke Aug 09 '14 at 16:35
  • Build your own parser that builds trees? See my SO answer: http://stackoverflow.com/a/25106688/120163 – Ira Baxter Aug 09 '14 at 16:45
  • @poke so that I could edit them, of course =) I need it for a Linq library which is heavily expression-based, and the compositions are quite bulky sometimes. – vines Aug 09 '14 at 16:54
  • @IraBaxter Yep, I consider writing one... But it will require me to study the subject a bit more, so I decided to ask first. – vines Aug 09 '14 at 16:56

1 Answers1

2

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"))

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • Thanks! Looks like a solution, I'll dig into it now. The only concern for now is that LINQKit depends on EntityFramework (at least that's what NuGet says). The project I work on is a lightweight library, which would rarely be used with EF, and making its users depend on EF is an overkill... – vines Aug 09 '14 at 20:53
  • 1
    @vines The original LINQKit (which you can download from the author's site) doesn't require EF. The maintainer of the NuGet package suggested to me to use [an older version of it](https://www.nuget.org/packages/LinqKit/1.0.0) if you don't want that dependency on EF 6. – svick Aug 10 '14 at 12:03