c#为什么List.Remove()会中断'for loop'

本文关键字:for loop 中断 List 为什么 Remove | 更新日期: 2023-09-27 18:01:19

我真的不知道为什么for循环只循环一次。我认为逻辑是正确的,下面是代码。

// the list is named 'dataList'
for(int i = 0 ; i < dataList.Count; i ++)
{
    string[] data = dataList[i].Split('+');
    string[] wsno = data[0].Split(':');
    if(wsno[1].Equals(tbWorkSheet.Text)) 
    {
        dataList.Remove(dataList[i])   <<<< remove string that has the same number
        //data removed
        //for loop ends up here idk why..
    }
}

dataList。Count将是列表的大小。

情况是这样的…我想删除存储在列表中的多个字符串,每个字符串都有它的组号。因此,for循环将循环到最后一个。但是,当它发现一个字符串与所需的数字相同时,它将执行if语句,即删除该字符串

c#为什么List.Remove()会中断'for loop'

这是一个非常糟糕的主意。通过从列表中删除这样的值,您将跳过列表中的下一项。

例如在索引0、1、2处有3个元素

第一次迭代i = 0删除索引0处的项。列表现在有索引为0,1的项(第一个项被删除)。

第二次迭代:i = 1。注意这里位于索引1的项是如何移动到0的。而我们的索引计数器从0变成1。所以我们将"跳过"这一项。

如果你的列表中只有2个项目,他会在第一次移除后打破。这是因为当索引增加时计数会减少。

按相反的顺序,你将消除这个问题。

List<int> list = new List<int> { 2, 1 };
for (int i = list.Count - 1; i >= 0; i--)
{
    list.RemoveAt(i);
}

编辑:正如Rawling提到的,当你删除项目时,如果减少你的计数器,你可以继续前进。

for (int i = 0; i < list.Count; i++)
{
    list.RemoveAt(i--);
}

您可以使用List。RemoveAll通用方法。方法从列表中删除与谓词匹配的所有项。方法签名如下:

int列表。RemoveAll(谓词匹配)

返回被删除元素的个数。

参见MSDN: http://msdn.microsoft.com/en-US/library/wdka673a(v=vs.110).aspx

您在删除项目后忘记减少i。这将跳过下一个项目,因为所有后续项目将被重新编号为1。

在列表中反向循环:

for(int i = dataList.Count; i >= 0 ; i--)
{
    string[] data = dataList[i].Split('+');
    string[] wsno = data[0].Split(':');
    if(wsno[1].Equals(tbWorkSheet.Text)) 
    {
        dataList.RemoveAt(dataList[i])   <<<< remove string that has the same number
        //data removed
        //for loop ends up here idk why..
    }
}

我宁愿做一个新的列表,而不是修改原来的集合。

可以用LINQ:

简洁地完成
dataList =
    dataList
        .Select(x => new{
            dataItem = x,
            secondWsno = x.Split('+').First().Split(':').Skip(1).First()
        })
        .Where(x => !x.secondWsno.Equals(tbWorkSheet.Text))
        .ToList();

不能在for循环中更改列表。您可以将要删除的数据保存在另一个列表中,然后在退出循环后将其删除。