Transform a delegate to a Expression Tree
I wonder if you can create and modify a Expression Tree out of a existing delegate.
Kinda like
public void Foo() {
开发者_StackOverflow Console.WriteLine(1000);
}
....
Expression exp = Foo.GetExpression();
//Now do something what changes 1000 to 2000...
So I would like to reverse engineer a allready excisting Method.
My problem is that I have a construction like this:
var acts = new Action[20];
for (int i = 0; i != 20; i++)
acts[i] = () => { Console.WriteLine(i); };
and by the way C# works all acts do the same (prints 20). But I want that that
acts[5]()
print 5
acts[11]()
prints 11 and so on.
So I need to compute 20 different delegates and I wonder what's a "nice" approach to do so. Of course I could just write:
acts[0] = () => Console.WriteLine(0);
acts[1] = () => Console.WriteLine(1);
acts[2] = () => Console.WriteLine(2);
acts[3] = () => Console.WriteLine(3);
....
But that's not a good approach in my eyey...
Anton's solution is nearly right, but he's copying the variable at the wrong time. You want this:
for (int i = 0; i != 20; i++)
{
int tmp = i;
acts[i] = () => Console.WriteLine(tmp);
}
This way the captured variable is tmp
rather than i
- and while there's only one i
variable, whose value changes on each iteration, you get a "new" tmp
variable for each iteration.
See Eric Lippert's blog posts on the topic (part 1, part 2) for more details.
(To answer the original question as per the title - you can't create an expression tree from a delegate in a useful way here - the only expression tree you can create is one which just calls the original delegate.)
Rewrite it like this:
for(int i = 0; i != 20; i++)
{
var x = i;
acts[i] = () => { Console.WriteLine(x); };
}
精彩评论