基本上,我想在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)
这给出了以下输出
>>>1
3
4
5
6
7
8
9
但是当在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);
}
}
提前致谢
答案 0 :(得分:25)
你不能这样做。来自IEnumerator<T>
的文档:
只要枚举器仍然有效 该系列保持不变。如果 对集合进行了更改, 例如添加,修改或删除 元素,枚举器是 不可恢复的无效及其 行为未定义。
替代方案是:
这些替代方案中的最后一个是类似LINQ的解决方案,您通常会在其中编写:
var newList = oldList.Where(x => ShouldBeRetained(x)).ToList();
(当然ShouldBeRetained
是你想要的任何逻辑。)只有你真正想要它在列表中时,才需要调用ToList()
。这导致更多的声明性代码,通常更容易阅读。我不能轻易猜出原始循环的意图(目前看起来很奇怪),而如果你可以纯粹用项目来表达逻辑,那么它可以更加清晰。
答案 1 :(得分: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");
请注意,这会修改初始列表。
答案 2 :(得分:1)
在使用foreach循环时,绝对不能以任何方式更改集合。
您可以使用for循环并自行管理索引或制作该集合的副本,并在循环原始文档时,从副本中删除与原始项目相同的项目。
在这两种情况下,它都不太清楚或方便:)。