表达式树动态编译实现运行时代码生成与缓存
利用Expression<TDelegate>构建动态方法并编译为委托,结合表达式缓存实现接近原生性能的运行时计算。 · 难度:入门 · +10XP
表达式树编译与缓存
当需要在运行时构建动态算法(如数学公式计算、规则引擎)时,反射性能不足,而Emit又过于复杂。本教程展示如何通过Expression类构建抽象语法树,再调用Compile()生成强类型委托。同时引入表达式缓存(Dictionary+锁或ConcurrentDictionary),避免重复编译相同结构。重点包括参数绑定、循环、条件分支以及闭包捕获,最终性能与手工编码接近。
public static Func<double, double> BuildPowerFunction(int exponent)
{
var param = Expression.Parameter(typeof(double), "x");
var body = Expression.Power(param, Expression.Constant(exponent));
return Expression.Lambda<Func<double, double>>(body, param).Compile();
}
// 缓存
var cache = new ConcurrentDictionary<int, Func<double, double>>();
var func = cache.GetOrAdd(3, BuildPowerFunction);
Console.WriteLine(func(2)); // 8