views:

54

answers:

2

Hello,

I wonder if you can create and modify a Expression Tree out of a existing delegate.

Kinda like

public void Foo() {
  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...

+2  A: 

Rewrite it like this:

for(int i = 0; i != 20; i++)        
{
    var x = i;
    acts[i] = () => { Console.WriteLine(x); };
}
Anton Gogolev
That will have the same problem.
Jon Skeet
Thanks both of you! That was what I wanted to know :)
Rico
+2  A: 

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.)

Jon Skeet
Ahh, completely missed the point. Thanks!
Anton Gogolev