c# - Different behaviors with a for loop and a foreach loop with closures -
i can't explain issue i've run across. different answer if use lambda syntax in foreach loop if use in loop. in code below register delegate in "dispatcher" class. later wrap delegate on way out in delegate , return list of these wrapped delegates. execute them. expected output of executing wrapped function list 1,2. don't see when combine lambda , foreach loop.
this not code causing problem, simplest case make reproduce it. prefer not discuss use cases of this, i'm more curious why behavior i'm not expecting. if use foreach loop below lambda syntax fails. if use new action() syntax , foreach works, if use lambda syntax in loop works. can explain going on here. has me stumped.
public class holder { public holder(int id, dispatcher disp) { this.id = id; disp.register(something); } public int id { get; set; } private void something(int test) { console.writeline(id.tostring()); } } public class dispatcher { list<action<int>> m_holder = new list<action<int>>(); public void register(action<int> func) { m_holder.add(func); } public list<action<int>> returnwrappedlist() { list<action<int>> temp = new list<action<int>>(); //for (int = 0; < m_holder.count; i++) //works - gives 1, 2 //{ // var action = m_holder[i]; // temp.add(p => action(p)); //} foreach (var action in m_holder) { temp.add(p => action(p)); //fails - gives 2,2 //temp.add(new action<int>(action)); works - gives 1,2 } return temp; } } class program { static void main(string[] args) { var disp = new dispatcher(); var hold1 = new holder(1, disp); var hold2 = new holder(2, disp); disp.returnwrappedlist().foreach(p => p(1)); } }
this infamous "closing on loop variable" gotcha.
Comments
Post a Comment