在迭代列表时向列表添加元素

问题描述 投票:0回答:2

我试图在迭代列表的同时将新元素添加到列表中

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);
          }
      }
}

几个循环后得到的错误是这样的:

Collection was modified; enumeration operation may not execute

我知道错误是由修改列表引起的,所以我的问题是:解决这个问题的最佳或最奇特的方法是什么?

谢谢

c# exception enumeration
2个回答
7
投票

您可能会在其他语言中遇到这种情况,但在 C# 中却不行。他们这样做是为了避免不明显的有趣的运行时行为。我更喜欢设置一个要添加的新内容列表,填充它,然后在循环之后插入它。

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);
    }
}

想象一下,如果你有一个 foreach 循环,并且每次都向其中添加一个元素,那么它永远不会结束!

希望这有帮助。


0
投票

是否需要这样做是值得怀疑的,但如果必须的话,请使用yield保留字创建一个新列表:

public IEnumerable<List<string>> SetExpander(List<List<string>> sets)
{
    foreach (var list in sets)
    {
        foreach (var c in X)
        {
            yield return list;
            var newSet = ir_a(list, c, productions);
            if (newSet.Any())
                 yield return newSet;
        }
    }
}

// then call is somewhere and use .ToList() to package it up

var sets = new List<List<string>>();
var expandedSets = SetExpander(sets).ToList();
© www.soinside.com 2019 - 2024. All rights reserved.