在C#编程中,表达式树(
Expression
)是一种
数据结构
,表达式树也称表达式目录树,是将代码以一种抽象的方式表示成一个对象树,树中每个节点本身都是一个表达式。
表达式树不是可执行代码,它是一种数据结构
。但是可以利用
LambdaExpression类
的派生类
Expression<TDelegate>
将
表达式树
转化成可执行的
Lambda表达式
的委托,当然也可以将
Lambda表达式
转化成
表达式树
。
表达式树
将表达式抽象成树状结构,每个节点代表表达式中的一个元素,如常量、变量、方法调用等。这种结构使得表达式易于分析和转换,同时也为动态生成代码和进行运行时分析提供了便利。
扩展:为什么要将表达式抽象成树形结构呢?
答:涉及到
树
的应用,其中一个应用为
表达式解析
,我们可以将
表达式
表示为树结构,
叶节点保存操作数,内部节点保存操作符
。
表达式层次决定计算的优先级,越底层的表达式,优先级越高
。如图中优先计算
(7+3)
和
(5-2)
再进行乘运算。其每一个子树都是一个表达式,子树计算后就成了一个节点。
表达式树
可以用于诸如
解析XML
和
JSON数据
、
LINQ查询
、
数据绑定
、
反射
还是其他领域,表达式树都是一个非常有用的工具。总结一下就是通常在写框架或底层时需要用到,日常场景上一般用不到。
// 创建表达式树:Lambda法
Expression<Func<int, int, int>> add = (x, y) => x + y;
Func<int, int, int> func = add.Compile();
func.Invoke(10, 20); // 输出:30
// 创建表达式树:组装法
// 创建一个 ParameterExpression 节点,该节点可用于标识表达式树中的参数或变量。
ParameterExpression x = Expression.Parameter(typeof(int), "x");
ParameterExpression y = Expression.Parameter(typeof(int), "y");
// 创建一个表示不进行溢出检查的算术加法运算的 BinaryExpression
BinaryExpression add = Expression.Add(x, y);
// 构造一个委托类型以及一个参数表达式的数组,创建 LambdaExpression。
Expression<Func<int, int, int>> addEx = Expression.Lambda<Func<int, int, int>>(add, new ParameterExpression[2]{
// 使用Compile该方法将表达式树重新转换为可执行代码
Func<int, int, int> func = addEx.Compile();
// 执行委托
func.Invoke(10, 20); // 输出:30