Convert Lambda Expression to Expression Tree in C
In C#, converting a lambda expression into an expression tree allows
you to treat code as data rather than executable instructions. This
article explains how the C# compiler handles this conversion
automatically through the System.Linq.Expressions
namespace, illustrates the syntax difference between standard delegates
and expression trees, and details how to inspect or compile the
resulting tree at runtime.
Implicit Conversion via Type Declaration
The primary way to convert a lambda expression into an expression
tree is by assigning the lambda directly to a variable of type
Expression<TDelegate>. When the C# compiler
encounters an assignment to Expression<TDelegate>, it
does not emit IL bytecode for a delegate; instead, it generates the
metadata and abstract syntax tree (AST) that represent the lambda.
using System;
using System.Linq.Expressions;
// 1. Compiled Delegate: Represents executable code
Func<int, bool> isEvenDelegate = num => num % 2 == 0;
// 2. Expression Tree: Represents the code structure as data
Expression<Func<int, bool>> isEvenExpression = num => num % 2 == 0;Explicit Casting
If you are passing a lambda to a method that accepts an
object or an untyped parameter, or if you are using the
var keyword, you must explicitly cast the lambda to the
target Expression<TDelegate> type.
var expression = (Expression<Func<int, int, int>>)((a, b) => a + b);Inspecting the Expression Tree
Once the lambda is converted into an expression tree, you can traverse its components, such as its parameters, body, and operation types:
Expression<Func<int, bool>> expr = x => x > 5;
// Access parameters
ParameterExpression parameter = expr.Parameters[0]; // 'x'
// Access the body
BinaryExpression body = (BinaryExpression)expr.Body; // 'x > 5'
Expression left = body.Left; // 'x'
Expression right = body.Right; // '5'
ExpressionType nodeType = body.NodeType; // GreaterThanCompiling and Executing at Runtime
An expression tree can be converted back into executable code at any
time using the Compile method, which produces an executable
delegate:
Expression<Func<int, int, int>> addExpr = (x, y) => x + y;
// Compile the tree to an executable delegate
Func<int, int, int> addFunc = addExpr.Compile();
// Execute the delegate
int result = addFunc(3, 4); // Returns 7Limitations
The C# compiler can only convert expression lambdas (lambdas with a single expression as the body) into expression trees. Statement lambdas enclosed in curly braces containing blocks, loops, or multiple statements cannot be automatically converted:
// Valid: Expression lambda
Expression<Action<int>> valid = x => Console.WriteLine(x);
// Compiler Error: Statement lambdas cannot be converted to expression trees
// Expression<Action<int>> invalid = x => { Console.WriteLine(x); };