I have a quick question hopefully about Action
types and Lambdas in C#. Here's come code:
static void Main(string[] args)
{
List<Action> actions = new List<Action>();
for (int I = 0; I < 10; I++)
actions.Add(new Action(() => Print(I.ToString())));
foreach (Action a in actions)
{
a.Invoke();
}
actions.Clear();
int X;
for (X = 0; X < 10; X++)
{
int V = X;
actions.Add(new Action(() => Print(V.ToString())));
}
foreach (Action a in actions)
{
a.Invoke();
}
Console.ReadLine();
}
public static void Print(string s)
{
Console.WriteLine(s);
}
If you run this code you will see that it outputs 10, ten times in a row, then outputs the numbers 0-9 the second time around. It clearly has something to do with the way I use X vs I, and how I give my action a new variable V each time in the second loop... Possibly that each new V is a new address in memory, but I'm struggling to understand why I.ToString() doesn't do the same thing in the first loop... Why doesn't I.ToString() used in the first Action work in the same way as the second example?
C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...
Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.
What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.
In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.
The for
loop is effectively expanded out to this by the compiler:
{
int I;
for (I = 0; I < 10; I++)
{
actions.Add(new Action(() => Print(I.ToString())));
}
}
This means that all the lambda instances capture the same instance of I
, which will be 10 when the loop exits.
In your second example you copy the value into a variable that is scoped to the body of the for
statement, and the lambda captures this local. There will be a unique local for each repetition of the loop.
It's important to realize that you don't capture the value of the variable, rather you capture the variable itself. That's why the first example doesn't work, but the second one does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With