Given the code below:
class Sample
{
public static void Run()
{
int i = 1;
Action<int> change = Increment();
for (int x = 0; x < 5; x++ )
{
change(i);
Console.WriteLine("value=" + i.ToString());
}
}
public static Action<int> Increment()
{
return delegate(int i) { i++; };
}
}
I get the answer:
value=1
value=1
value=1
value=1
value=1
value=1
Instead of 1, 2, 3 … 6.
This is from an article on the net with links to clues but I can’t work out why this is. Anyone have any ideas?
Your parameter is being passed by value.
Writing
i++will change the value ofito a differentintvalue (unlike a mutable type).When you write
i++inside the delegate, you’re changing the parameter to be equal to a differentintvalue. However, this does not affect the local variable whose value was copied to the parameter.To solve this, you need to make a delegate with a
refparameter.refparameters are passed by reference. Therefore, when you change aref intparameter to a differentintvalue, you’ll also change the local variable or field whose reference was passed as the parameter.For more information, see here.
Since the
Actiondelegates do not takerefparameters, you’ll need to make your own delegate type, like this: