表达式树问题:Lambda函数参数未映射到Expression Parameter
表达式树生成偶数判断Lambda时参数未正确映射的问题解决
你碰到的问题根源很明确:你在Expression.Block的变量列表里重复声明了Lambda的参数numParam,这相当于在Block作用域内创建了一个全新的同名局部变量,直接覆盖了外部传入的Lambda参数——这个内部变量的默认值是0(int类型的默认值),所以你看到打印的永远是0,根本没用到你实际传入的参数。
修正后的代码
public static Func<int, bool> Generate_IsEven_Func() { var numParam = Expression.Parameter(typeof(int), "numParam"); var returnValue = Expression.Variable(typeof(bool), "returnValue"); var consoleWL = typeof(Console).GetMethod(nameof(Console.WriteLine), new[] { typeof(int) }); var body = Expression.Block( // 只声明局部变量returnValue,不要包含外部参数numParam new[] { returnValue }, // 现在会正确引用传入的Lambda参数 Expression.Call( null, consoleWL, numParam ), Expression.Assign(returnValue, Expression.Constant(false, typeof(bool))), Expression.IfThen( Expression.Equal( Expression.Modulo( numParam, Expression.Constant(2, typeof(int)) ), Expression.Constant(0, typeof(int)) ), Expression.Assign(returnValue, Expression.Constant(true, typeof(bool))) ), returnValue ); var lambda = Expression.Lambda<Func<int, bool>>(body, numParam).Compile(); return lambda; }
为什么这样修改?
- Lambda表达式的参数
numParam属于Lambda的外部作用域,不需要在Block的变量列表中再次声明。当你把它加入Block的变量数组时,表达式树会在Block内部生成一个新的局部变量,这个变量和外部参数完全无关,初始值为int的默认值0,自然不会映射你传入的实际参数。 - 只需要在Block的变量列表中声明你真正需要的局部变量
returnValue,numParam作为Lambda的参数可以直接在Block内部使用,这样就能正确关联到你传入的数值了。
测试验证
调用修改后的方法:
var isEvenMethod = Generate_IsEven_Func(); var cond = isEvenMethod(21); Console.WriteLine(cond);
控制台会输出:
21 False
传入偶数比如22时,会输出:
22 True
完全符合预期。
内容的提问来源于stack exchange,提问作者dimitar.d
相关产品推荐
相关产品推荐

