8

From C# in depth:

Not all lambda expressions can be converted to expression trees. You can’t convert a lambda with a block of statements ( even just one return statement ) into an expresion tree --> it has to be in the form that just evaluates a single expression.

Since Linq-to-Object statements don't get converted into expression tree objects, the lambda expressions used with Linq-to-Object operators can contain a block of statements

        string[] count = { "one ", "two ", "three ", "four ", "five ", "six " };
        IEnumerable<int> result = count.Select(item =>
                               {
                                   Console.WriteLine(item);
                                   return item.Length;
                               });
        foreach (int i in result);

OUTPUT:

one two three four five six

I haven't yet started learning Linq-To-Sql or Linq-To-Entities, but I assume lambda expressions used with LINQ statements that operate on IQueryable<T> can only ever contain a single expression, due to restristion that only a single expression can be converted into an expression tree?

Thank you

2 Answers 2

18

It's not just that they can only contain a single expression - it's can't be a statement lambda at all. Even a block like this:

var result = query.Select(item => { return item.Length; });

would be invalid for LINQ to SQL. It would have to be expressed as:

var result = query.Select(item => item.Length);

(I've just noticed that that's the bit of the book you quoted. Oh well - it shows I'm consistent :)

Note that as of .NET 4, expression trees themselves do have the ability to contain blocks, but the C# compiler can't translate statement lambdas into that kind of expression tree. There are other restrictions too, but they rarely cause problems.

This is specified in section 4.6 of the C# 4 spec:

Not all anonymous functions can be represented as expression trees. For instance, anonymous functions with statement bodies and anonymous functions containing assignment expressions cannot be represented. In these cases, a conversion still exists, but will fail at compile-time.

Sign up to request clarification or add additional context in comments.

6 Comments

Now, what on earth would you know about something mentioned in C# in Depth? Oh, never mind.
@Jon: It suddenly occurred to me how very related this question is to that at stackoverflow.com/questions/8405423/… wink wink
Jon, what do you mean when you say it can't be a statement lambda? The question shows sample code using a statement lambda and it outputs the correct values.
@Nick: It uses a statement lambda... But converts it into a delegate, not an expression tree.
Expression tree does not execute code rather than generating data, where later you can compile it back to code.
|
1

You are correct, they can only ever contain a single expression.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.