foreach and linq query - need help trying to understand please

Viewed 1992

I have a linq query, the results of which I iterate over in a foreach loop.

The first is a query which grabs a collection of controls from a table layout panel, I then iterate over the collection and remove the controls from the tableLayoutPanel thus:

var AllItems = (from Item in this.tableLayoutPanel1.Controls.OfType<ItemControl>()
                select Item);

foreach (ItemControl item in AllItems)
{
    Trace.WriteLine("Removing " + item.ToString());
    this.tableLayoutPanel1.Controls.Remove(item);
    item.Dispose();
}

The above does not do as I expected (i.e. Throw an error), it removes only half the controls (the ODD numbered ones) it appears that on each iteration the AllItems reduces it's self, and though the underlying collection is being modified no error is thrown.

If I do simmilar with an array of strings:

        string[] strs = { "d", "c", "A", "b" };
        List<string> stringList = strs.ToList();

        var allitems = from letter in stringList
                       select letter;

        foreach (string let in allitems)
        {
            stringList.Remove(let);

        }

This time Visual studio throws an error (as expected) complaining that the underlying collection has changed.

Why does the first example not blow up too?

There is something about Iterators/IEnumerable that I am not understanding here and I wonder if someone could help me understand what is going on under the hood with linq and foreach.

(I am aware that I can cure both issues by AllItems.ToList(); before I iterate, but would like to understand why the second example throws an error and the first does not)

3 Answers
Related