RSS

Delegate In Foreach Iteration Bug – Solution

17 Jun

Problem:

When declaring delegates (anonymous methods) inside of foreach loop, the container only get the last delegate calculated.
The reason is that the foreach loop is designed to reuse declared variables, in our case the delegate is used as a type declared before the loop and reused.

Example code:

//C#
string[] StrArr = {"1","2"};
foreach(string tmp in StrArr)
{
   this.Invoke(delegate {
      MessageBox.Show(tmp);
   });
}

Result:  “2” will be displayed twice.

Solution:

Use for loop instead.

Example code:

//C#
string[] StrArr = {"1","2"};
for(int i = 0; i < StrArr.Length; i++)
{
   string tmp = StrArr[i];

   this.Invoke(delegate {
      MessageBox.Show(tmp);
   });
}

Reference:

http://smellegantcode.wordpress.com/2008/06/13/the-classic-delegateforeach-interaction-bug-and-a-solution/

Advertisements
 

Tags: , , , , , ,

One response to “Delegate In Foreach Iteration Bug – Solution

  1. earwicker

    June 17, 2011 at 11:42 am

    Here is a fixed version using ‘foreach’:

    foreach(string tmp in StrArr)
    {
    var localCopy = tmp;
    this.Invoke(delegate {
    MessageBox.Show(localCopy);
    });
    }

    And here is a broken version using ‘for’:

    for(int i = 0; i < StrArr.Length; i++)
    {
    this.Invoke(delegate {
    MessageBox.Show(StrArr[i]);
    });
    }

    Clearly it has nothing to do with whether we use 'for' or 'foreach'! 🙂

    What makes the difference is whether we declare a second variable inside the loop, and copy the loop variable into it.

     

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: