Wednesday, September 15, 2010

Access to modified closure !

My colleague asked me do you know about the warning re-sharper gives called " Access to modified closure"...
I said ... Nope.. and what he told me was fascinating !


Lets say you have a code something like this:


            List strList=new List();
            strList.Add("one");
            strList.Add("two");
            strList.Add("three");
            strList.Add("four");

            int y = 20;
            foreach (string s in strList)
            {
                Button btn =new Button();
                btn.Text = s;
                btn.Location=new Point(10,y);
                btn.Click += delegate
                                 {
                                     MessageBox.Show(s);
                                 };
                panel1.Controls.Add(btn);
                y += 40;
            }

What it does is, creates a button and adds it to a panel, the text is set as the string in the list and click event shows the string in the message.


What really happens is ... you get buttons with text as "one", "two", "three", "four" but if you click all of them, all of them show "four" !!


This is because, the modified value of the variable is never passed to the closure, which is our anonymous delegate here.


The solution is:


            List strList=new List();
            strList.Add("one");
            strList.Add("two");
            strList.Add("three");
            strList.Add("four");

            int y = 20;
            foreach (string s in strList)
            {
                string s1 = s;
                Button btn =new Button();
                btn.Text = s;
                btn.Location=new Point(10,y);
                btn.Click += delegate
                                 {
                                     MessageBox.Show(s1);
                                 };
                panel1.Controls.Add(btn);
                y += 40;
            }

Get the value in a separate variable and pass that variable each time in the delegate.

No comments:

Post a Comment