closures - Captured variable in a loop in C# -
i met interesting issue c#. have code below.
list<func<int>> actions = new list<func<int>>(); int variable = 0; while (variable < 5) { actions.add(() => variable * 2); ++ variable; } foreach (var act in actions) { console.writeline(act.invoke()); }
i expect output 0, 2, 4, 6, 8. however, outputs 5 10s.
it seems due actions referring 1 captured variable. result, when invoked, have same output.
is there way work round limit have each action instance have own captured variable?
yes - take copy of variable inside loop:
while (variable < 5) { int copy = variable; actions.add(() => copy * 2); ++ variable; }
you can think of if c# compiler creates "new" local variable every time hits variable declaration. in fact it'll create appropriate new closure objects, , gets complicated (in terms of implementation) if refer variables in multiple scopes, works :)
note more common occurrence of problem using for
or foreach
:
for (int i=0; < 10; i++) // 1 variable foreach (string x in foo) // , again, despite how reads out loud
see section 7.14.4.2 of c# 3.0 spec more details of this, , article on closures has more examples too.
Comments
Post a Comment