C
Join ServerC#
help
Combine two Expression Func [Answered]
Qque11249/14/2022
I have two
Expression<Func<A,A>>
. I want to combine them into a single Expression<Func<A,A>>
that runs the output of the first through the second. How can I do that?Tthinker2279/14/2022
Couldn't you create a new expression which is the equivalent of
(x) => b(a(x))
?Qque11249/14/2022
I would like to combine the expressions programatically as opposed to writing the combo by hand. @thinker227
Tthinker2279/14/2022
hold on
AAlphar9/14/2022
Expression<Func<T, T>> chain = x => e2.Compile()(e1.Compile()(x));
Maaaybe this?
Qque11249/14/2022
Can't compile ahead of time that's done later in the process
Qque11249/14/2022
This eventually becomes SQL. Needs to stay as a proper expression.
AAlphar9/14/2022

Tthinker2279/14/2022
This works
Expression<Func<int, int>> a = (int x) => x - 2;
Expression<Func<int, int>> b = (int x) => x * 2;
var param = Expression.Parameter(typeof(int), "x");
var c = Expression.Lambda<Func<int, int>>(Expression.Invoke(a, Expression.Invoke(b, param)), param);
var func = c.Compile();
int i = func(7);
Qque11249/14/2022
Testing
Qque11249/14/2022
My case is actually A->B and B->B so I need to adapt it slightly
Qque11249/14/2022
Okay able to run yours as is. thanks you!
Qque11249/14/2022
Working on modifying now
Qque11249/14/2022
@thinker227 any idea what I might being doing wrong here?
Expression<Func<List<int>, int>> a = x => x[0];
Expression<Func<int, int>> b = x => x * 2;
var param = Expression.Parameter(typeof(int), "x");
var listParam = Expression.Parameter(typeof(List<int>), "x");
var c = Expression.Lambda<Func<List<int>, int>>(
Expression.Invoke(a, Expression.Invoke(b, listParam)), param);
var func = c.Compile();
int i = func(new List<int>() {5,6,7});
Console.WriteLine(i);
Qque11249/14/2022
System.ArgumentException: Expression of type 'System.Collections.Generic.List`1[System.Int32]' cannot be used for parameter of type 'System.Int32'
Tthinker2279/14/2022
I think you only need one param
Tthinker2279/14/2022
The lambda you're expecting is a
Func<List<int>, int>
so you can't pass in a parameter of type intTthinker2279/14/2022
Replace
param
with listParam
and it should work™️Qque11249/14/2022
Isn't the param when you call b different ?
Qque11249/14/2022
Since B accepts an int vs A accepting a List<int>
Tthinker2279/14/2022
oh, yeah
Tthinker2279/14/2022
Right you have to do it in the reverse order, swap
a
and b
Qque11249/14/2022
Okay sec testing
Qque11249/14/2022
Got it
Qque11249/14/2022
You are right we only need one param
Qque11249/14/2022
Expression<Func<List<int>, int>> a = x => x[0];
Expression<Func<int, int>> b = x => x * 2;
var param = Expression.Parameter(typeof(int), "x");
var listParam = Expression.Parameter(typeof(List<int>), "x");
var interMediate = Expression.Invoke(a, listParam);
var c = Expression.Lambda<Func<List<int>, int>>(Expression.Invoke(b, interMediate), listParam);
var func = c.Compile();
int i = func(new List<int>() {5,6,7});
Console.WriteLine(i);
Qque11249/14/2022
$ 10
Qque11249/14/2022
Thank you for the help!
Qque11249/14/2022
Now I just gotta convert this to my real types haha should be ez
AAccord9/14/2022
✅ This post has been marked as answered!