Linq Expressions – From and to delegates

I’m getting quite a few hits on my blog regarding Linq Expressions and how to convert those to and from delegates, so I figure I can just as well make a small post about it.

From Delegate to Expression;

This is not really possible, you can never cast or convert an existing delegate into an expression tree.
You can however assign lambda expressions to expression trees exactly the same way as you assign them to a delegate.

//assign a lambda expression to a delegate
Func<int> myDelegate = () => 1 + 2 + a +b;

or:

//assign a lambda expression to an expression tree
Expression<Func<int>> myExpressionTree = () => 1 + 2 + a +b;

Notice that you do exactly the same thing, except that the expression tree version wraps the delegate type inside a generic expression class.
The C# compiler will figure out what your intentions are and compile the code in completely different ways for those two cases.
This is the reason why you can not use “var” as the type for a lambda assignment, the compiler have no way to figure out if you want a delegate or an expression tree, or even what type the delegate should have.

The first case will generate an anonymous method that is assigned to the delegate var “myDelegate”.
While the expression tree version will complile the expression into code that builds the expression tree and then asigns the result to the Expression var “myExpressionTree”.

You can also pass lambda expressions exactly the same way;

//pass a lambda expression as a delegate

Foo( () => 1 + 2 + a +b );

....

void Foo (Func<int> myExpressionTree)
{..}

or:

//pass a lambda expression as an expression tree

Foo( () => 1 + 2 + a +b );

....

void Foo (Expression<Func<int>> myExpressionTree)
{..}

Note that the calling code looks exactly the same in both cases, it is only the definition of the methods that are called that differs.
This is also how Linq to Objects and Linq to SQL works.

The Linq to Objects provider uses delegates, while the Linq to SQL provider receives expression trees that are later converted into ad hoc SQL statements.

So in short, the compiler can compile the same expressions into two different forms, but you can not cast or convert from a delegate into an expression tree.

From Expression to Delegate;

Linq expression can not be casted or converted into delegates, they can however be “compiled” into delegates.

eg:

//create an linq expression
Expression<Func<int>> myExpressionTree = () => 1 + 2 + a +b;

//compile the expression into a delegate
Func<int> myDelegate = myExpression.Compile();

The above code is ofcourse useless, you should of course not create expressions and then immediately compile them into delegates.
That would be silly since you could assign the lambda into a delegate directly.

However, there are cases where you might want to add code in between the creation of the expression and the delegate compilation.
eg. you might want to analyze the expression and take certain actions depending on the contents of the expression tree and if some criteria is met, compile the delegate.

The most common reason why you would want to compile linq expressions into delegates is however a completely different story.
Since .NET 3.5 , there are a complete namespace of expression classes.
You can manually build expression trees using those classes and call compile on that tree in order to compile it into CIL code.
This means that you can use the Linq Expression trees as the foundation of a simple compiler.

And as of .NET 4.0, we are getting even more power for our expression trees, the entire Dynamic Language Runtime is build around the Linq Expressions.
So you can build expression trees containing if statements, for loops, variable declarations, assignments etc etc.

But more about that in another post :-)

//Roger

17 thoughts on “Linq Expressions – From and to delegates”

  1. I have developed an expression tree visualizer that generates it as a graph (or a real tree — not a treeview) on a WPF canvas.

    The source of the test program is @ sixpairs.com (not the sources to the libraries though); you can play around with it using any type of C# expression.

    The interface is pretty simple:

    ExpressionTree.Display(expr) –> Canvas

    The canvas will contain a graphviz-based graph rendered in WPF (you don’t need to install graphviz; it does not use the dot notation or the corresponding console utilities in an external process).

  2. (not sure if my comment went through…)

    To take a delegate and create an expression tree, you could attempt to fetch the delegate’s method body, then parse the IL. You’ll need to interpret it into suitable expression trees, which means you’re interpreting the IL to determine what’s going on, but nothing more than what Reflector or FxCop are in the business of doing.

    See:

    http://msdn.microsoft.com/en-us/library/system.delegate.getmethodimpl.aspx
    http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getmethodbody.aspx
    http://msdn.microsoft.com/en-us/library/system.reflection.methodbody.aspx

  3. @Keith

    >>To take a delegate and create an expression tree, you could attempt to fetch the delegate’s method
    >>body, then parse the IL. You’ll need to interpret it into suitable expression trees

    Yes, that will be doable in .NET 4 when the expression classes are extended to support standard constructs like loops and assignments.

    (You can ofcourse do some of that right now in 3.5, but there are alot more support for it in 4.0)

    1. Of course, you could use pass dynamic objects through a delegate and record what calls are made, and try to make some sense out of that. It works (I’ve done so). But it’s ugly.

  4. Here is a quick thought:
    Func methoddelegate = this.testmethod;
    Expression action = () => methoddelegate(“1”, 2, new TestClass());
    MethodCallExpression method = action.Body as MethodCallExpression;

    based on what I know you can’t get an expression tree from a delegate because it isn’t an actual method call, it is just a definition. A similar situation would be to try and get the expression tree of an object, ex: Thread.

  5. Func<string, int, TestClass, int> methoddelegate = this.testmethod;
    Expression<Action> action = () => methoddelegate(“1”, 2, new TestClass());
    MethodCallExpression method = action.Body as MethodCallExpression;

    reposted to fix invalid characters

  6. I use this for error logging which uses the logic previously posted. this creates a string representation of the method with parameter values.

    example usage: ToString(() => somemethod(someparameter));

    string ToString(Expression<Action> action)
    {
    MethodCallExpression call = action.Body as MethodCallExpression;
    if (call == null) throw new ArgumentException();

    StringBuilder message = new StringBuilder(call.Method.Name + “(“);

    foreach (MemberExpression member in call.Arguments)
    {
    object paramvalue = (member.Expression as ConstantExpression).Value;
    FieldInfo field = paramvalue.GetType().GetField(member.Member.Name);

    object actualvalue = field.GetValue(paramvalue);
    if (actualvalue is string)
    {
    actualvalue = “\”” + actualvalue + “\””;
    }

    message.Append(“(” + field.FieldType.ToString() + “) ” + field.Name + ” = ” + actualvalue.ToString() + “, “);
    }

    message.Remove(message.Length – 2, 2);
    message.Append(“)”);

    return message.ToString();
    }

  7. @Onur Gamus

    From the site you linked:
    “”” There’s no builtin feature to do that, it’s not a straightforward process. You basically have to decompile the compiled method. “”””

    Writing a decompiler is a bit too drastic to most of us.
    Just as splitting atoms is ;-)

  8. @Roger:

    “Writing a decompiler is a bit too drastic to most of us.”

    Drastic, perhaps, but that’s precisely what happenned immediately after PDC05, if you were hanging out on the LINQ Forums. (I forget whether you were or not.) :)

    Personally, I would rather just have everything as an expression tree that were invocable. Not difficult. Can be done in a couple lines of code. Would be nice if it (like many things) were OOB.

  9. @mbarbac —

    Indeed, note my comments from 3 Feb…

    And boy is it a pain in the butt. I’d rather they just allow us to create Expression<Func> (which was my motivation). I can come up with reasons why they can’t, but I don’t have to like the situation.

    Congratulations on actually writing an article about it. :)

  10. @Keith:
    Thanks.
    And agree! The CLR/DLR should provide a full-powered conversion utility. But since it happens, at least we have the solution I present in the article that is usefull for LINQ-like scenarios, and maybe others.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s