在c#中使用foreach循环时修改集合

Llo*_*ell 8 c# python invalidoperationexception

基本上,我想在foreach循环中删除列表中的项目.我知道在使用for循环时这是可能的,但出于其他目的,我想知道使用foreach循环是否可以实现这一点.

在python中,我们可以通过执行以下操作来实现此目的:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

for i in a:
    print i

    if i == 1:
        a.pop(1)
Run Code Online (Sandbox Code Playgroud)

这给出了以下输出

>>>1
3
4
5
6
7
8
9
Run Code Online (Sandbox Code Playgroud)

但是当在c#中做类似的事情时,我得到一个InvalidOperationException,我想知道是否有办法解决这个问题,而不仅仅是使用for循环.

我抛出异常时使用的c#代码:

static void Main(string[] args)
  {
  List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9"});

  foreach (string Item in MyList)
    {
    if (MyList.IndexOf(Item) == 0)
      {
      MyList.RemoveAt(1);
      }

    Console.WriteLine(Item);
    }
  }
Run Code Online (Sandbox Code Playgroud)

提前致谢

Jon*_*eet 25

你不能这样做.来自以下文档IEnumerator<T>:

只要集合保持不变,枚举器仍然有效.如果对集合进行了更改(例如添加,修改或删除元素),则枚举数将无法恢复,并且其行为未定义.

替代方案是:

  • 建立要删除的新项目列表,然后将其全部删除
  • 使用一个正常的"for"循环,并确保你小心不要翻过同一个元素两次或遗漏任何一个.(你已经说过你不想这样做,但你想做的事情是行不通的.)
  • 构建一个仅包含要保留的元素的新集合

最后一种替代方案是类似LINQ的解决方案,您通常会在其中编写:

var newList = oldList.Where(x => ShouldBeRetained(x)).ToList();
Run Code Online (Sandbox Code Playgroud)

(ShouldBeRetained当然,无论你想要什么逻辑,它都在哪里.)ToList()只有当你真正想要它在一个列表中时才需要调用.这导致更多的声明性代码,通常更容易阅读.我不能轻易猜出你原来的循环是什么意思(目前看起来很奇怪),而如果你可以纯粹根据项目来表达逻辑,那么它可以更加清晰.


Dar*_*rov 6

如果您只需删除满足条件的所有项目,则可以使用List <T> .RemoveAll方法:

List<string> MyList = new List<string>(new string[] { "1", "2", "3", "4", "5", "6", "7", "8", "9" });
MyList.RemoveAll(item => item == "1");
Run Code Online (Sandbox Code Playgroud)

请注意,这会修改初始列表.