The author recently studied the concept of expression trees and wrote this article to reinforce understanding. If there are any errors, please comment and point them out~
Concept of Expression Trees
- The creation of expression trees can be done using Lambda method and Assembly method.
- To learn about expression trees, one needs the foundation of Delegates, Lambda, Func<>.
- The shape of an expression tree can reference a binary tree.
- An expression tree can be understood as a mathematical expression.
Mathematical expression constants and symbols serve as the bottom nodes of the expression tree. Each computation generates a result which is a node, or their common node represents the operation they should perform.
Generating Expression Trees
Expression trees can be created using Lambda expression method and Assembly method.
For convenience, the expression generated here is ( i * j ) + ( x * y ).
Their computation is as follows
Generating Expression Trees with Lambda
To create an application in the console, you need to include:
using System.Linq.Expressions;
1. Create an expression
(The system automatically converts the Lambda expression into an expression tree; however, not all Lambda expressions can be converted, refer to the section “System automatically converts Lambda expressions to expression trees” at the end of the article for details).
Expression<Func<int, int, int, int, int>> func = (i, j, x, y) => (i * j) + (x * y);
2. Output the system-converted expression
After entering this line of code and running it, check the console output of the expression tree.
Console.WriteLine(func);
3. Convert code to data
(Using code as data)
var compile = func.Compile(); // or Func<int, int, int, int, int> compile = func.Compile();
4. Substitute numbers for computation
int result = compile(12, 13, 14, 15); // Substitute specific numbers into the expression and compute Console.WriteLine(result); // Output the expression result
The complete code is as follows:
Expression<Func<int, int, int, int, int>> func = (i, j, x, y) => (i * j) + (x * y); Console.WriteLine(func); //Output expression<span style="color: #0000ff;">var</span> compile = func.Compile(); <span style="color: #008000;">//</span><span style="color: #008000;">Convert code to data </span><span style="color: #008000;">//</span><span style="color: #008000;">or Func<int, int, int, int, int> compile = func.Compile();</span> <span style="color: #0000ff;">int</span> result = compile(<span style="color: #800080;">12</span>, <span style="color: #800080;">13</span>, <span style="color: #800080;">14</span>, <span style="color: #800080;">15</span>); <span style="color: #008000;">//</span><span style="color: #008000;">Substitute specific numbers into the expression and compute</span> Console.WriteLine(result); <span style="color: #008000;">//</span><span style="color: #008000;">Output the expression result</span> Console.ReadKey();</pre>
Console Output:
Generating Expression Trees with Assembly Method
Expressions consist of "symbols" and operators.
Use ParameterExpression type to modify parameters and instantiate parameters using Expression.Parameter(Type type, string name).
1. Generate parameters a, b, and d
ParameterExpression a = Expression.Parameter(typeof(int), "i"); ParameterExpression b = Expression.Parameter(typeof(int), "j"); ParameterExpression c = Expression.Parameter(typeof(int), "x"); ParameterExpression d = Expression.Parameter(typeof(int), "y");
Analysis:
i, j, x, y are node names, a, b, c, d are instance names. There's no need to waste energy thinking about the naming conventions for a, b, c, d, i, j, x, y above.
ParameterExpression indicates creating a node, while Parameter represents a named parameter expression; for more details, please refer to the section “Classification of Expression Parameters” later in the article.
Expression.Parameter(Type type, string name) indicates the properties of this node.
2. Generate nodes
Expression r1 = Expression.Multiply(a, b); //Multiplication operation Expression r2 = Expression.Multiply(c, d); //Multiplication operation
Analysis:
Two operations ( i * j ) and ( x * y ) have been created.
Multiply denotes a multiplication operation that does not perform overflow checking. The Expression class has 85 operation methods; further details on addition, subtraction, multiplication, division, and comparisons will be provided in the section “Arithmetic Operators” later in the article.
3. Generate Endpoint
Expression result = Expression.Add(r1, r2); // Addition
4. Generate Expression Tree, Transform, Output Expression Tree, Substitute Data for Calculation
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d); var com = func.Compile(); Console.WriteLine("Expression" + func); Console.WriteLine(com(12, 12, 13, 13));
The complete code is as follows:
ParameterExpression a = Expression.Parameter(typeof(int), "i"); ParameterExpression b = Expression.Parameter(typeof(int), "j");Expression r1 </span>= Expression.Multiply(a, b); <span style="color: #008000;">//</span><span style="color: #008000;"> Multiplication Operation</span> ParameterExpression c = Expression.Parameter(<span style="color: #0000ff;">typeof</span>(<span style="color: #0000ff;">int</span>), <span style="color: #800000;">"</span><span style="color: #800000;">x</span><span style="color: #800000;">"</span><span style="color: #000000;">); ParameterExpression d </span>= Expression.Parameter(<span style="color: #0000ff;">typeof</span>(<span style="color: #0000ff;">int</span>), <span style="color: #800000;">"</span><span style="color: #800000;">y</span><span style="color: #800000;">"</span><span style="color: #000000;">); Expression r2 </span>= Expression.Multiply(c, d); <span style="color: #008000;">//</span><span style="color: #008000;"> Multiplication Operation</span>
Expression result = Expression.Add(r1, r2); // Addition
// The above code generates nodes
// Generates Expression
Expression<Func<int, int, int, int, int>> func = Expression.Lambda<Func<int, int, int, int, int>>(result, a, b, c, d);
var com = func.Compile();
Console.WriteLine("Expression" + func);
Console.WriteLine(com(12, 12, 13, 13));
Console.ReadKey();
Console Interface
Supplementary Notes
1. The system automatically converts Lambda expressions into expression trees
The requirement for lambda expressions can only be represented by the input parameters and return parameters. Lambda expressions cannot contain other constructs such as conditionals or loops.
Example of an error

Expression<Func<int, int, int, int, int>> func = (a, b, c, d) => { if (a < 10) { a += 1; } /* * Other operation code */ return a + b + c + d; };
View Code
Remove all those elements, modified as follows:
Expression<Func<int, int, int, int, int>> func = (a, b, c, d) => a + b + c + d;
This "simplest" lambda expression can be automatically converted into an expression tree by the system.
2. Arithmetic Operators
In general mathematics, there are operations such as addition, subtraction, multiplication, division, modulus, and exponentiation, while in programming, there are more options for arithmetic operators, reaching 85 types.
The author provides a diagram listing some methods.
Official list of arithmetic operators by Microsoft https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.expression?view=netframework-4-7-2
It is estimated that everyone may find Microsoft's documentation a bit unsatisfactory~ Here is a recommended list translated and organized by a great expert https://blog.csdn.net/zhuqinfeng/article/details/70168337
3. Expression Parameters
Using the mathematical ellipse perimeter formula: L = 2πb + 4(a-b) , where a is the length of the semi-major axis and b is the length of the semi-minor axis, for example:
Parameter is similar to an unknown in mathematics, such as a, b; methods of use:
ParameterExpression a = Expression.Parameter(typeof(int), "a")
ParameterExpression b = Expression.Parameter(typeof(int), "b")
Constant represents a constant, for example in 2πb, it can be 2 or 2π; methods of use:
ConstantExpression define = Expression.Constant(2);
For more classifications of parameters, please refer to https://blog.csdn.net/zhuqinfeng/article/details/70168337
Here is a part of the captured image:
4. Methods for Operations in Expression
Methods representing operations such as addition, subtraction, multiplication, and division. The following diagram illustrates this:
Multiply(a,b) denotes multiplication, while Add(r1,r2) denotes addition.
Of course, it’s not that simple; they all have related overloaded methods and advanced uses.
For more information, please check https://blog.csdn.net/zhuqinfeng/article/details/70168337
Here are some screenshots:
5. Advanced Uses of Expression Trees
Expression trees can be combined with database queries or LINQ, deriving many advanced operations.
For example, dynamic querying, traversing expression trees, converting to a SQL WHERE clause, etc. Due to space constraints, the author will not elaborate further.
You can view all types of objects in System.Linq.Expressions at the following link:
https://docs.microsoft.com/en-us/dotnet/api/system.linq.expressions?view=netframework-4.7.2
Study hard and make progress every day~ Hope to succeed in the interview on the 3rd.
文章评论