如何将MethodCallExpression与Lambda表达式结合编译,实现回调触发
解决方案
你的核心需求是把原有Lambda表达式与指定Action回调结合,编译成一个新的Func<T, TResult>,确保每次调用该委托时先触发Action,再执行原Lambda的逻辑。现有代码的问题在于错误传递了参数信息而非实际参数值,且未将Action调用与原Lambda逻辑组合。
修正后的完整代码
public Func<T, TResult> Get<T, TResult>(Object obj, Action<object> action = null) { Expression<Func<T, TResult>> lambda = GetLambdaExpression<T, TResult>(obj); // 未传入action时直接返回原Lambda编译结果 if (action == null) { return lambda.Compile(); } // 获取原Lambda的输入参数(T类型) var parameter = lambda.Parameters[0]; // 构建action调用表达式:将T类型参数转为object后传入action var actionCall = Expression.Call( Expression.Constant(action.Target), action.Method, Expression.Convert(parameter, typeof(object)) ); // 合并逻辑:先执行action调用,再返回原Lambda的执行结果 var newBody = Expression.Block( actionCall, lambda.Body ); // 创建新Lambda并编译为委托 var newLambda = Expression.Lambda<Func<T, TResult>>(newBody, parameter); return newLambda.Compile(); }
关键逻辑说明
- 参数适配:原Lambda参数为
T类型,而Action<object>需要object类型输入,通过Expression.Convert完成类型转换,保证参数能正确传入action。 - 逻辑组合:使用
Expression.Block将action调用与原Lambda执行逻辑合并为一个代码块,严格保证先触发action、再返回原Lambda结果的执行顺序。 - 空值兼容:增加action为null的判断,避免空引用异常,此时直接返回原Lambda的编译结果。
内容的提问来源于stack exchange,提问作者Dexter Morgan
相关产品推荐
相关产品推荐

