How to capture local variables in a C # loop
This article mainly introduces how to capture local variables in the C# cycle, with a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, let the editor take you to understand it.
Question:
I have an interesting problem. The code looks something like this.
List actions = new List (); int variable = 0bot while (variable)
< 5){ actions.Add(() =>Variable * 2); + + variable;} foreach (var act in actions) {Console.WriteLine (act.Invoke ());}
My expected output is 0Perry 2, 4, 4, 6, 8, but the final output is five 10s, which looks like these action contexts all capture the same variable.
Is there a flexible way to achieve the expected results I want?
Solution:
The workaround is to use an intermediate variable in your loop loop body and feed it into the lambda body, as shown in the following code:
List actions = new List (); int variable = 0bot while (variable)
< 5){ int variable1 = variable; actions.Add(() =>Variable1 * 2); + + variable;} foreach (var act in actions) {Console.WriteLine (act.Invoke ());} Console.ReadLine ()
In fact, this can also happen in multithreading, such as the following code:
For (int counter = 1; counter Console.Write (counter). Start ();}
You think you will print out the final result, which is very interesting. In my case, the output result is: 2, 1, 3, 3, 4, the result on your side must be different.
The only solution is to use local variables, and the modified code is as follows:
For (int counter = 1; counter Console.Write (localVar)). Start ();} Summary
There may be many friends who don't know why the code is correct after adding a variable1 variable. To analyze, you can look at the IL code generated by C #.
Private static void Main (string [] args) {List actions = new List (); for (int variable = 0; variable < 5; variable++) {c__DisplayClass0_0 cantilever DisplayClass0 = new c__DisplayClass0_0 (); c__DisplayClass0_.variable1 = variable; actions.Add (new Func (c__DisplayClass0_.b__0));} foreach (Func act in actions) {Console.WriteLine (act ());} Console.ReadLine ();}
You can clearly see that the so-called variable1 has become a field under the anonymous class c__DisplayClass0_0, and every time in the foreach loop is new, so this field must be different, which ensures the correct result.
Thank you for reading this article carefully. I hope the article "how to capture local variables in the C# cycle" shared by the editor will be helpful to everyone. At the same time, I also hope that you will support and pay attention to the industry information channel. More related knowledge is waiting for you to learn!