最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Chain MethodCallExpression with Expression - Stack Overflow

programmeradmin1浏览0评论

I am trying to have MethodCallExpression compiled with a lambda expression. Basically i want a method to be called everytime the lambda expression is invoked.

I am not sure i'm even on the right path but so far i got,

public Func<T, TResult> Get<T, TResult>(Object obj,  Action<object> action = null)
{
     Expression<Func<T, TResult>> lambda = GetLambdaExpression<T, TResult>(obj);
     var parameterValue = action.Method.GetParameters().Single();
     var callback = Expression.Call(Expression.Constant(action.Target), action.Method, Expression.Constant(parameterValue)); 
     return lambda.Compile(); 
    
}

I need to somehow combine the lambda and the action callback and compile them into a Func<T, TResult>. Something like this:

obj => { action(obj); return lambda(obj); }

I am trying to have MethodCallExpression compiled with a lambda expression. Basically i want a method to be called everytime the lambda expression is invoked.

I am not sure i'm even on the right path but so far i got,

public Func<T, TResult> Get<T, TResult>(Object obj,  Action<object> action = null)
{
     Expression<Func<T, TResult>> lambda = GetLambdaExpression<T, TResult>(obj);
     var parameterValue = action.Method.GetParameters().Single();
     var callback = Expression.Call(Expression.Constant(action.Target), action.Method, Expression.Constant(parameterValue)); 
     return lambda.Compile(); 
    
}

I need to somehow combine the lambda and the action callback and compile them into a Func<T, TResult>. Something like this:

obj => { action(obj); return lambda(obj); }
Share Improve this question edited Feb 7 at 0:24 Ivan Petrov 4,5452 gold badges11 silver badges23 bronze badges asked Feb 6 at 18:35 Dexter MorganDexter Morgan 12710 bronze badges 7
  • 1 I'm confused about what you are trying to achieve. What does it mean to have a "combined lambda and callback"? What exact type does GetLambdaExpression return? What exactly do you want to happen? – Charlieface Commented Feb 6 at 18:51
  • GetLambdaExpression returns Expression<Func<T, TResult>> i need the callback to be compiled into that so that it will run first before executing the lambda logic.. – Dexter Morgan Commented Feb 6 at 19:08
  • 1 What does it mean "compiled with that" I still don't get what you want to happen. Can you give an example of what you want the resulting expression to do, in pseudo-code eg obj => { var o = lambda(obj); action(o); return obj; } or maybe obj => { action(obj); return lambda(obj); } – Charlieface Commented Feb 6 at 19:12
  • Same here. Could you say what X problem you're solving by "trying to have MethodCallExpression compiled with a lambda expression"? – IV. Commented Feb 6 at 19:15
  • 3 So why do you need any of this expressions and stuff? Why don't you actually just return that exact lambda var func = lambda.Compile(); return obj => { action(obj); return func(obj); } – Charlieface Commented Feb 7 at 2:05
 |  Show 2 more comments

1 Answer 1

Reset to default 2

Judging from the comments under the question, I think you are after this:

// Example values for obj/Action params
// and what GetLambdaExpression would return from your code
object obj = 42;
Action<object> action = (ob) => Console.WriteLine($"Action on {ob}");
Expression<Func<int, int>> lambda = a => a + 3;

// actual logic

// this is for the unlikely case that action has
// other callbacks chained via += and we want all of them to
// uncomment next line to demo
// action += (ob) => Console.WriteLine("AnotherAction on" + ob);
var invokeMethodInfo = typeof(Action<object>).GetMethod("Invoke");

var lambdaParam = lambda.Parameters.FirstOrDefault();
var lambdaParmCastObject = Expression.Convert(lambdaParam, typeof(object));
var actionMethodcallExpression = Expression.Call(Expression.Constant(action),
invokeMethodInfo, lambdaParmCastObject);

var body = Expression.Block(actionMethodcallExpression,
    Expression.Invoke(lambda, lambdaParam));

var newLambda = Expression.Lambda<Func<int, int>>(body, lambdaParam);

// Testing code
var compiled = newLambda.Compile();
Console.WriteLine("Invoking");
int result = compiled(3);
Console.WriteLine($"Result of Lambda: {result}");

Output:

Invoking
Action on 3
Result of Lambda: 6
发布评论

评论列表(0)

  1. 暂无评论