score:9

Accepted answer

False. There are some overloads of Expression.Block to do it.

What is true is that you can't create a lambda expression through the use of the C# compiler that has a variable, but that is a limitation of the compiler.

So you can't

Expression<Func<int>> exp = () => {
    int v = 1;
    return v;
};

but you can

var variable = Expression.Variable(typeof(int));
var lambda = Expression.Lambda<Func<int>>(
    Expression.Block(
        new[] { variable }, 
        Expression.Assign(variable, Expression.Constant(1)), 
        variable)); // With lambda expressions, there is an implicit
                    // return of the last value "loaded" on the stack

since that is a variable declaration statement, and the API does not support statement lambdas.

This was true in .NET < 4.0 . In .NET 4.0 Microsoft added Expression methods to build nearly everything that can be present in the body of a method (there are some missing "things", like unsafe code keywords/operators, plus there are the primitives but there aren't complex constructs like the for or lock, that can be built on top of other constructs). Note that 90% of those added things are incompatible with LINQ-to-SQL/EF.

score:5

Well, you can use Expression.Block to declare a block which contains local variables...

For example:

using System;
using System.Linq.Expressions;

public class Test
{    
    static void Main()
    {
        var x = Expression.Variable(typeof(int), "x");
        var assignment1 = Expression.Assign(x, Expression.Constant(1, typeof(int)));
        var assignment2 = Expression.Assign(x, Expression.Constant(2, typeof(int)));

        var block = Expression.Block(new[] { x }, new[] { assignment1, assignment2 });
    }
}

That builds an expression tree equivalent to:

{
    int x;
    x = 1;
    x = 2;
}

The C# compiler doesn't use this functionality within lambda expression conversions to expression trees, which are currently still restricted to expression lambdas, as far as I'm aware.


Related Articles