一段统计分数的 C# 代码,跑起来就是红字:System.IndexOutOfRangeException,后面跟着「索引超出了数组界限」。盯着看了半天,数组明明赋值了。

问题在循环条件。写成 i <= arr.Length,最后一次 i 正好等于长度,而数组下标最大只到 Length - 1。

for (int i = 0; i <= arr.Length; i++)

上面这行改一个字符就好:把 <= 换成 <。差一错误是最常见的越界来源,尤其是从 1 开始编号的业务数据。

报错行不一定是出事的地方

异常信息里带行号,但那个行号指向的是取元素那一下,不是下标算错的地方。所以要往回找,看谁给这个下标赋的值。

异常里的 Actual value 也别放过,它通常写着你越界的那个下标,比如 5,一眼能看出是循环多跑了一次。

多维数组更容易混。arr[i, j] 里两个维度的上界分别是 GetLength(0) - 1 和 GetLength(1) - 1。拿第二维的长度去限第一维,小数据测不出来,数据一多就崩。

几类常见的越界来源

  • 业务上从 1 开始编号,直接拿来当下标。
  • Split 之后没判断长度就取第二个元素。
  • 循环里 Remove 元素,Count 变了,下标没跟着变。
  • 接口返回空数组,代码默认至少有一个元素。

还有一种更隐蔽的:数组是接口反序列化来的,字段名对不上,长度是 0,代码却直接取第一个元素。这类问题看日志里的原始响应最快。

数组如果是集合转出来的,注意转换发生在循环前还是循环后。循环中途往里加了元素,长度就对不上了。

怎么让它早点暴露

取之前加一句长度判断,不够就走另一条分支。这比 catch 住异常靠谱,catch 只能兜底,兜完你也不知道丢了几条数据。

调试时把 Length、Count、当前下标一起打印出来,一眼能看出是 0 还是差一。断点打在循环入口,看 i 和 Length 的比值,比单步快。

这类错误九成是边界没算对,跟数组本身没关系。写循环时把 < 和 <= 念一遍,能省很多时间。