Consider the following C# code

Expression<Func<int, int>> expression = a => a + 1;

Because the C# compiler sees that the lambda expression is assigned to an Expression type rather than a delegate type it generates an expression tree roughly equivalent to this code

ParameterExpression parameterA = Expression.Parameter(typeof(int), "a");
var expression = (Expression<Func<int, int>>)Expression.Lambda(
                                                 Expression.Add(
                                                     parameterA,
                                                     Expression.Constant(1)),
                                                 parameterA);

The root of the tree is the lambda expression which contains a body and a list of parameters. The lambda has 1 parameter called “a”. The body is a single expression of CLR type BinaryExpression and NodeType of Add. This expression represents addition. It has two subexpressions denoted as Left and Right. Left is the ParameterExpression for the parameter “a” and Right is a ConstantExpression with the value 1.

The simplest usage of this expression is printing it:

Console.WriteLine(expression); //prints a => (a + 1)

Which prints the equivalent C# code.

The expression tree can be compiled into a C# delegate and executed by the CLR

Func<int, int> lambda = expression.Compile();
Console.WriteLine(lambda(2)); //prints 3

Usually expressions are translated to other languages like SQL, but can be also used to invoke private, protected and internal members of public or non-public types as alternative to Reflection.