Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wrap a linq expression with another linq expression

I was thinking if without writing an ExpressionVisitor it's possible to solve this issue

Expression<Func<int, int, int>> multiply = (n1, n2) => n1 * n2;

Expression<Func<int, Expression<Func<int, int, int>>, Expression<Func<int, int>>>> power2 = 
              (adad, tabe) => Expression.Invoke(tabe, 
                                   Expression.Constant(adad), Expression.Constant(adad));

power2.Compile()(2, multiply);

the only point that I can't figure out is how to convert the invocation expression to the return type. if I set the return type to dynamic then it looks fine, but I wonder if there is better option to do that

like image 274
Mohammad Hossein Amri Avatar asked Mar 28 '19 08:03

Mohammad Hossein Amri


1 Answers

Try something like this:

Expression<Func<int, Expression<Func<int, int, int>>, Expression<Func<int>>>> power2 =
    (o, f) => Expression.Lambda<Func<int>>(Expression.Invoke(
                  f, Expression.Constant(o), Expression.Constant(o)));

and then expression is:

var r = power2.Compile()(4, multiply);
//r = {() => Invoke((n1, n2) => (n1 * n2), 4, 4)}

if you want to invoke r then:

var r = power2.Compile()(4, multiply).Compile()();
//r is 16

n.b. I have changed the signature to return only Func<int> because the actual argument will be already embedded during the compilation.

like image 196
Johnny Avatar answered Oct 21 '22 09:10

Johnny