Click here to Skip to main content
Click here to Skip to main content

Tagged as

Editing Enumerator within foreach loop (well, not really)

, 26 Jan 2011
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

Comments and Discussions

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