Consider the following code:
public class TestEvent {
public event EventHandler FireUp;
public void InvokeFireUp() {
if (FireUp != null) FireUp(this, EventArgs.Empty);
}
}
class Program {
static void Main(string[] args) {
List<TestEvent> fires = new List<TestEvent>();
for (int i = 0; i < 10; i++) {
TestEvent t = new TestEvent();
t.FireUp += delegate { Console.WriteLine(i); };
fires.Add(t);
}
foreach (TestEvent t in fires) t.InvokeFireUp();
Console.ReadLine();
}
}
If you are expecting it to print the numbers from 1 to 10 then you’re wrong
The thing is, external variables used in anonymous delegates are passed by reference (even value types like int). In the loop, the variable i is not recreated but increased by one. In the end, i will contain the last value and every event fired will simply write down the value 10. To work as intended, you should write the loop as follows:
for (int i = 0; i < 10; i++) {
int j = i;
TestEvent t = new TestEvent();
t.FireUp += delegate { Console.WriteLine(j); };
fires.Add(t);
}
Because j is defined “inside” the loop, it will always be a new variable (and hence a new reference in memory).
Tags: C#, Computers, Programming