For a game in which you have to code your own AI, I need to enqueue various method calls with parameters. For example:
MessageReceived(string text, Source source);
MiningCompleted(ResourceData data);
This has to be done, to call all Events at the beginning of the next step of the game and not instantly. Now I have written a small prove of concept for passing parameters to the methods:
namespace LambdaTest
{
class Program
{
static void Main(string[] args)
{
Queue<Action> q = new Queue<Action>();
for (int i = 0; i < 5; i++)
{
q.Enqueue(new Action(() => {
// Methods should be called here
Console.WriteLine(i);
}));
}
foreach (Action a in q)
a();
Console.ReadLine();
}
}
}
The first thought was it has to work.
After seeing the output of 5x5 my question was, why doesn't it output 0 to 4 and why does it actually work, because i
doesn't exist in this scope anymore.
It outputs 5 five times because by the time you're executing the actions, i
is 5. There's only a single i
variable, and its lifetime is extended until all anonymous functions that have captured it are eligible for garbage collection.
To fix this, just introduce a separate variable inside the loop which takes a copy of the loop variable:
for (int i = 0; i < 5; i++)
{
// Declared *inside* the loop, so each iteration will have a separate variable
int copy = i;
q.Enqueue(() => Console.WriteLine(copy));
}
See more on this question at Stackoverflow