Add elements to a list while iterating over it

14,403

You might get away with this in other languages but not C#. They do this to avoid funny runtime behaviour that isn't obvious. I prefer to set up a new list of things you are going to add, populate it, and then insert it after the loop.

public class IntDoubler
{
    List<int> ints;

    public void DoubleUp()
    {
        //list to store elements to be added
        List<int> inserts = new List<int>();

        //foreach int, add one twice as large
        foreach (var insert in ints)
        {
            inserts.Add(insert*2);
        }
        //attach the new list to the end of the old one
        ints.AddRange(inserts);
    }
}

Imagine that if you had a foreach loop, and you added an element to it each time, then it would never end!

Hope this helps.

Share:
14,403
CodeXtack
Author by

CodeXtack

Updated on July 11, 2022

Comments

  • CodeXtack
    CodeXtack almost 2 years

    I'm trying to add new elements to a list of lists while iterating over it

    List<List<String>> sets = new List<List<string>>();
    
    foreach (List<String> list in sets)
    {
          foreach (String c in X)
          {
              List<String> newSet = ir_a(list, c, productions);
    
              if (newSet.Count > 0)
              {
                  sets.Add(newSet);
              }
          }
    }
    

    The error I get after a few loops is this:

    Collection was modified; enumeration operation may not execute
    

    I know the error is caused by modifying the list, so my question is: What's the best or most fancy way to sort this thing out?

    Thanks

    • Alexei Levenkov
      Alexei Levenkov almost 7 years
      Can you please clarify why regular solutions did not work (i.e. for or clone)
    • CodeXtack
      CodeXtack almost 7 years
      @AlexeiLevenkov I tried using a for loop; but after the first loop, the program froze, not letting me go to the next step, and all I can do is stop the debug mode.
  • RJM
    RJM almost 7 years
    Your description of creating a new list and adding it after the loop is correct. But the code you provide above doesn't do that. It does the same thing the OP's code does....namely, it inserts into the same list that is being iterated.
  • pseudoabdul
    pseudoabdul almost 7 years
    Sorry I just fixed a typo. I was inserting into the wrong list. They key difference between OP's code and mine is that OP is trying to alter the collection being iterated WITHIN the loop, where as I use a buffer to modify it outside of the loop.
  • Admin
    Admin almost 7 years
    The same typo in reverse: foreach (var insert in inserts) should probably be foreach (var insert in ints).
  • CodeXtack
    CodeXtack almost 7 years
    This goes well with a list of integers, however, mine is not a list of integers
  • pseudoabdul
    pseudoabdul almost 7 years
    I only used ints as an example. The same is true for a collection of any type. Simply replace int with any other type and try it out.