You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何移除列表中21~32范围元素的代码会触发IndexOutOfRangeException异常?

解决List移除元素时的IndexOutOfRangeException问题

嘿,我来帮你理清这个索引越界的问题!作为有4年经验的开发者,这种看似简单的遍历移除坑确实容易踩中~

问题根源

你代码的核心问题在于固定循环次数(硬写了k < 6)和移除元素后List长度动态变化的矛盾:

  • 当你调用changedNums.RemoveAt(k)时,List的长度会立刻减1,后续元素会向前移动一位填补被移除的位置。
  • 但你的循环还是坚持跑满6次,而且k一直在递增。比如,当你移除第0个元素后,List长度变成5,但k会继续走到5,此时访问changedNums[5]自然会触发IndexOutOfRangeException。
  • 另外,正向遍历移除还会导致你跳过元素:比如移除第0个元素后,原来的第1个元素现在在第0位,但k变成1,直接跳过了这个元素的检查。

三种解决方案

1. 反向遍历(最稳妥的手动遍历方式)

从List的最后一个元素往前遍历,这样移除元素不会影响前面未遍历的元素索引,既不会跳过元素,也不会出现越界:

// nums是一个恰好包含6个元素的List<int>
List<int> changedNums = new List<int>(nums);
for (int k = changedNums.Count - 1; k >= 0; k--)
{
    if (changedNums[k] >= 21 && changedNums[k] <= 32)
    {
        changedNums.RemoveAt(k);
    }
}

2. 使用LINQ过滤(最简洁的方式)

直接用LINQ的Where方法过滤掉目标范围的元素,一行代码搞定,完全避免手动遍历的索引问题:

// nums是一个恰好包含6个元素的List<int>
List<int> changedNums = nums.Where(num => num < 21 || num > 32).ToList();

3. 正向遍历但动态调整索引(适合必须正向遍历的场景)

如果一定要正向遍历,需要在移除元素时调整k的取值,同时用List的实时长度作为循环条件:

// nums是一个恰好包含6个元素的List<int>
List<int> changedNums = new List<int>(nums);
int k = 0;
while (k < changedNums.Count)
{
    if (changedNums[k] >= 21 && changedNums[k] <= 32)
    {
        changedNums.RemoveAt(k);
        // 移除元素后,下一个元素移到当前k的位置,所以不递增k
    }
    else
    {
        k++; // 不需要移除时,再移动到下一个元素
    }
}

总结

你的原代码用固定的6次循环没有考虑List长度的动态变化,加上正向遍历移除的索引偏移问题,才导致了越界异常。上面的三种方法都能完美解决这个问题,其中LINQ的方式最简洁易读,推荐优先使用~

内容的提问来源于stack exchange,提问作者Benjamin Zvolenszki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 00:02:45