0Pricing
C# Academy · 课时

什么是表达式树

了解如何将代码表示为数据结构。

什么是表达式树 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。

代码即数据

表达式树会将代码表示为一种可以在运行时检查的数据结构,而不是只能运行的已编译指令。C# 使用Expression<TDelegate>实现这一点。

Lambda 到委托与表达式树

将 Lambda 赋给Func<...>后,您会得到可运行的代码。将同一个 Lambda 赋给Expression<Func<...>>后,编译器会构建一棵描述该 Lambda 的树。

using System;
using System.Linq.Expressions;

Func<int, int> runnable = x => x + 1;          // compiled delegate
Expression<Func<int, int>> tree = x => x + 1;  // data structure

Console.WriteLine(runnable(5));   // 6
Console.WriteLine(tree);          // x => (x + 1)

检查表达式树

由于表达式树是数据,您可以读取其中的各个部分:参数、body 和节点类型。

using System;
using System.Linq.Expressions;

Expression<Func<int, int>> tree = x => x + 1;
Console.WriteLine(tree.Parameters[0].Name); // x
Console.WriteLine(tree.Body.NodeType);      // Add
Console.WriteLine(tree.ReturnType);         // System.Int32

表达式层次结构

每个节点都派生自System.Linq.Expressions.Expression。常见类型包括BinaryExpression、ParameterExpression、ConstantExpression和MethodCallExpression。

using System;
using System.Linq.Expressions;

Expression<Func<int, int>> tree = x => x + 1;
var body = (BinaryExpression)tree.Body;
Console.WriteLine(body.Left);  // x
Console.WriteLine(body.Right); // 1

仅允许单表达式 Lambda

您只能将单表达式 Lambda 转换为表达式树。带语句体的 Lambda(包含花括号)不能转换为表达式树。

using System;
using System.Linq.Expressions;

Expression<Func<int, int>> ok = x => x * 2;    // fine
// Expression<Func<int,int>> bad = x => { return x*2; }; // compile error
Console.WriteLine(ok); // x => (x * 2)

为什么这很重要

表达式树让库能够理解您的代码,而不只是运行它。LINQ 提供程序可以将表达式树转换为 SQL、动态查询或其他目标语言。

NodeType 告诉您操作类型

NodeType属性是一个ExpressionType枚举值,用于标识该节点执行的操作。

using System;
using System.Linq.Expressions;

Expression<Func<int, bool>> tree = x => x > 10;
Console.WriteLine(tree.Body.NodeType); // GreaterThan

常量与参数

ParameterExpression代表一个 input;ConstantExpression则保存嵌入代码中的字面值。

using System;
using System.Linq.Expressions;

Expression<Func<int, int>> tree = x => x + 5;
var body = (BinaryExpression)tree.Body;
Console.WriteLine(body.Left.GetType().Name);  // ParameterExpression (or TypedParameterExpression)
Console.WriteLine(((ConstantExpression)body.Right).Value); // 5

表达式树中的方法调用

调用方法的 Lambda 会变成MethodCallExpression,并公开该方法及其参数。

using System;
using System.Linq.Expressions;

Expression<Func<string, int>> tree = s => s.Length;
// member access here; a call example:
Expression<Func<string, string>> call = s => s.ToUpper();
var mc = (MethodCallExpression)call.Body;
Console.WriteLine(mc.Method.Name); // ToUpper

表达式树是不可变的

表达式树是不可变的。要“更改”表达式树,您需要根据其各个部分构建一棵新树,这正是访问器和重写器的工作方式。

综合运用

这里将端到端分析一棵小型谓词树:参数、运算符和常量。

using System;
using System.Linq.Expressions;

Expression<Func<int, bool>> isAdult = age => age >= 18;
var body = (BinaryExpression)isAdult.Body;
Console.WriteLine(isAdult.Parameters[0].Name);          // age
Console.WriteLine(body.NodeType);                       // GreaterThanOrEqual
Console.WriteLine(((ConstantExpression)body.Right).Value); // 18

快速检查

请确认表达式树的特殊之处。

回顾

您已经学习了表达式树的含义。

  • Expression<TDelegate>将代码表示为可检查的数据。
  • 节点包括参数、常量、二元运算和方法调用。
  • 只有单表达式 Lambda 才符合要求。
  • 表达式树是不可变的;重写会构建新树。

常见问题解答

「什么是表达式树」课时是免费的吗?

是的 — 「什么是表达式树」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。

「什么是表达式树」这节课中我会学到什么?

了解如何将代码表示为数据结构。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C# Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「什么是表达式树」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C# Academy 课中编写并运行代码吗?

能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 什么是表达式树
  2. 手动构建表达式
  3. 编译和执行表达式
  4. LINQ 提供程序中的表达式树
← 返回 C# Academy