C#面试题更新 2026-08-05

请解释 C# 中 Expression 类型的作用,并说明构建与编译动态表达式树的具体步骤。

技术原理C#

考察说明

考察对C#表达式树概念、构建方式及编译执行流程的理解。

回答思路

  1. 【回答框架 1】Expression 类型是 C# 中用于表示代码逻辑为数据的抽象语法树(AST),它允许在运行时分析、修改和执行代码。其核心作用是将 Lambda 表达式或代码片段转换为可编程操作的结构化对象。
  2. 【回答框架 2】构建表达式树通常通过 Expression 类的静态方法(如 Expression.Add、Expression.Property)手动组合节点,或直接转换 Lambda 表达式(如 Expression<Func<int,int>> expr = x => x + 1;)。使用 Lambda 表达式时,编译器自动生成表达式树。
  3. 【回答框架 3】编译表达式树通过调用 Expression<TDelegate>.Compile() 方法,生成对应委托类型(如 Func<int,int>)的可执行代码。Compile 方法将表达式树转换为 IL 指令,然后 JIT 编译为机器码。
  4. 【回答框架 4】动态构建时,需要根据条件组合节点,并注意类型匹配和参数绑定。例如,构建算术表达式时可先创建 ParameterExpression,再通过 BinaryExpression 表示运算,最后用 LambdaExpression 包装。
  5. 【回答框架 5】编译后的委托可以直接调用,但若表达式树频繁变动,编译开销较大,可缓存结果以提升性能。
  6. 【关键点 1】Expression 类型表示可编程的 AST,用于动态生成代码。
  7. 【关键点 2】构建可用手动节点组合或直接 Lambda 表达式转换。
  8. 【关键点 3】通过 Compile() 编译为委托,随后可执行。
  9. 【关键点 4】编译开销需考虑,适合动态场景但避免频繁编译。
  10. 【易错点 1】混淆 Expression 与 Func:Expression 可被分析和修改,Func 仅可执行。
  11. 【易错点 2】忽略表达式树不可变性,修改需重新构建。
  12. 【易错点 3】编译复杂表达式时忽略类型安全检查,导致运行时异常。