Click here to Skip to main content
11,712,727 members (81,141 online)
Click here to Skip to main content

Tagged as

Editing Enumerator within foreach loop (well, not really)

, 26 Jan 2011 CPOL 3.6K 3
Rate this:
Please Sign up or sign in to vote.
A simple way to edit a list or collection which is iterated in a foreach loop
Recently, I had to process a Collection of class objects after a split over some properties. I did the split through a relatively simple Select and Distinct extension methods. The next task was to split the result again in batches and process. I discovered this while doing that. The ToList extension method, supposedly, creates a deep copy of the IEnumerator returned by the LINQ expression. Following is a simple code to demonstrate.

class Animals
{
    public bool Herbivore { get; set; }
 
    public bool IsMammal { get; set; }
 
    public string CommonName { get; set; }
}
 
private static void SendBatches()
{
    Collection<Animals> animalCollection = new Collection<Animals>();
 
    animalCollection.Add(new Animals { Herbivore = true, IsMammal = true, CommonName = "Cow" });
    animalCollection.Add(new Animals { Herbivore = false, IsMammal = true, CommonName = "Cat" });
    animalCollection.Add(new Animals { Herbivore = false, IsMammal = true, CommonName = "Dog" });
    animalCollection.Add(new Animals { Herbivore = true, IsMammal = true, CommonName = "Lamb" });
 
    // Ignoring those weird mammals who lay eggs
    var herbivores = (from animal in animalCollection
                      where animal.Herbivore
                      select new { Name = animal.CommonName, LaysEggs = !animal.IsMammal });
 
    foreach (var herbivore in herbivores)
    {
        if (herbivore.Name.StartsWith("C", StringComparison.InvariantCultureIgnoreCase))
        {
            animalCollection.Remove(animalCollection.Where(x => string.Compare(x.CommonName, herbivore.Name, true) == 0).First());
        }
    }
}

As expected, the foreach will fail at the second iteration since we have changed the Enumerator. But, if we change the LINQ expression to the following, it works:

var herbivores = (from animal in animalCollection
                              where animal.Herbivore
                              select new { Name = animal.CommonName, LaysEggs = !animal.IsMammal }).ToList();

Even ToArray gives the same behavior.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

d@nish
Software Developer Self Employed
India India
No Biography provided

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150819.1 | Last Updated 26 Jan 2011
Article Copyright 2011 by d@nish
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid