Considering this code:
public class Foo
{
public int a { get; set; }
public int b { get; set; }
}
private void Test()
{
List<Foo> foos = new List<Foo>();
foos.Add(new Foo());
foos.Add(new Foo());
Expression<Func<Foo, int>> exp0 = f => f.a * f.b;
Expression<Func<int>> exp1 = () => foos[0].a * foos[0].b;
Expression<Func<int>> exp2 = () => foos[1].a * foos[1].b;
}
How can you take exp0
and turn it into two expressions identical to exp1
and exp2
. Note that I don't want to just evaluate exp0
for each Foo
in foos
, but instead get two new expressions.
[Update]:
Basically, I want to be able to expand or "flatten" an expression passed to a Linq
extension method such as Sum
into one expression per item in the enumeration since these enumerations will be static, and because I already have code that reads expressions that don't take parameters (and then turns them into another language).
I'm using the MetadataToken
as a references to properties that have a certain attribute (in this case a
and b
would have this attribute) and using it with a dictionary that correlates C# properties to another language's variables:
Foo foo = new Foo();
Expression<Func<int>> exp = () => foo.a * foo.a + foo.b;
string result1 = GetResult(exp); // gets "v_001 * v_001 + v_002"
List<Foo> foes = new List<Foo>();
foes.Add(new Foo());
foes.Add(new Foo());
Expression<Func<int>> exp2 = () => foes.Sum(f => f.a * f.a + f.b);
string result2 = GetResult(exp2); // should get "(v_001 * v_001 + v_002) + (v_003 * v_003 + v_004)"
I would do it this way:
Write a parameter-replacer expression-visitor that manipulates the original expression as follows:
Here's a quick and dirty sample I whipped up based on my earlier answer on a different question:
Usage for your scenario (tested):