An ↑ expression tree is a tree-like data structure in which each node represents an expression.
An ↑ expression is a sequence of operators and operands.
The operators of an expression indicate which operations to apply to the operands.
There are three kinds of operators:
- Unary operators. The unary operators take one operand and use either prefix notation, such as
–x
, or postfix notation, such asx++
- Binary operators. The binary operators take two operands and all use infix notation, such as
x + y
- Ternary operator. Only one ternary operator exists:
?:
. It takes three operands and uses infix notation:c ? x : y
↑ Infix, Prefix, and Postfix Expressions.
Certain operators can be overloaded.
↑ C# operators and expressions
An operand is an element of an expression.
Operands can be variables, functions, pointers, and other objects:
- In the expression
2 + 3
, the numbers2
and3
are the operands - In the command
x = 5
, the number5
and the variablex
are the operands
Operands along with operators determine the meaning and behavior of an expression.
To create expression trees by using the API, use the Expression
class.
You can compile and run code represented by expression trees. This enables dynamic modification of executable code, the execution of LINQ queries in various databases, and the creation of dynamic queries.
The definition of "executing an expression tree" is specific to a query provider. For example, it may involve translating the expression tree to a query language appropriate for an underlying data source.
Expression trees are immutable. If you want to modify an expression tree, you must construct a new expression tree by copying the existing one and replacing nodes in it.
When a lambda expression is assigned to a variable of type Expression<TDelegate>
, the compiler emits code to build an expression tree that represents the lambda expression.
The C# compiler can generate expression trees only from expression lambdas — single-line lambdas:
Expression<Func<int, bool>> lambda = number => number < 5;
The C# compiler cannot parse statement lambdas — multi-line lambdas.
The ↑ Expression
class provides the base class from which the classes that represent expression tree nodes are derived. It also contains static
factory methods to create the various node types.
The ↑ Expression<TDelegate>
class represents a strongly typed lambda expression as a data structure in the form of an expression tree.
An expression can be translated into a delegate, but the backward conversion is not possible.
The ↑ Expression<TDelegate>.Compile
method compiles the lambda expression described by the expression tree into executable code and produces a delegate that represents the lambda expression.
Expression<Func<int, bool>> expression = x => x == 1;
Func<int, bool> delegate1 = expression.Compile();