tags:

views:

1244

answers:

4

why can not i use foreach loop to drop items from listbox:

   
 protected void btnRemove_Click(object sender, EventArgs e)
        {
            ListBox listbox = Controltest2.FindControl("ListBox1") as ListBox;
            if (Controltest2.Items.Count > 0)
            {
                foreach (ListItem li in listbox.Items)
                {
                    if (li.Selected)
                    {
                        Controltest2.Remove(li.Value);
                    }
                }
            }
        }

This codes give me error to drop item from listbox. On the other hand;

   ListBox listbox = Controltest2.FindControl("ListBox1") as ListBox;
            if (Controltest2.Items.Count > 0)
            {
                int count = Controltest2.Items.Count;
                for (int i = count - 1; i > -1; i--)
                {
                    if (listbox.Items[i].Selected)
                    {
                        Controltest2.Remove(listbox.Items[i].Value);
                    }
                }
            }

Why cannot i use "Foreach loop" instead of "for loop"...

+13  A: 

The foreach statement repeats a group of embedded statements for each element in an array or an object collection. The foreach statement is used to iterate through the collection to get the desired information, but should not be used to change the contents of the collection to avoid unpredictable side effects

Source: MSDN foreach

Note: emphasis mine

dirkgently
+1  A: 

Short answer: When you iterate over a loop using foreach, you can't add or remove items being looped over

Jeramy Rutley
+4  A: 

When you use the foreach loop, you are modifying the underlying collection, thereby interupting the enumerator so to speak. If you want to use the foreach loop, try the following:

foreach (ListItem li in listbox.Items.ToArray())
{
    if (li.Selected)
    {
        Controltest2.Remove(li.Value);
    }
}

Note: the call to ToArray() in this example assumes LINQ to object and depending on the situation, you may be required to also call the Cast<T>() prior to calling it. The main point that I am trying to get across here is that by creating an array, the foreach is now iterating over the array's enumerator instead of the ListBox's enumerator, allowing you to modify the ListBox's collection at will.

Swim
A: 

In the first example, you're removing items from the start of the collection, which affects the collection which defines the conditions of the iteration, whereas in the second case, you're removing items from the end of the collection each time, and the loop initial conditions are unaffected because of the fixed value of int count.

Rafe Lavelle