c# 检查循环索引 + 中断结果在 IndexOutOfRange 中?

c# Checking Index of Loop + Break Results in IndexOutOfRange?

所以是的,这是一个简单的 IndexOutOfRange 异常——不要讨厌我。但是,我正在做的事情 应该 有效,但不是。我在 Unity 中使用 C#。我将不胜感激任何帮助!

在下面的代码中,我需要访问列表中的下一个键。如果在 [i] 之后没有找到密钥,则跳出循环。简单的...? 出于某种原因,它似乎没有进行检查。

for (int i = 0; i < keys.Count; i++)
{
    // if the number of keys is less than the hypothetical next index, then exit the loop
    if (keys.Count < i + 1)
        break;

    // I am getting the error for this line
    Key nextKey = keys[i + 1];
    // do something with nextKey...

 }

我敢肯定有人会建议只在 for 循环中执行 keys.Count-1,但是当我这样做时,脚本的其他部分无法按预期工作。必须有另一种方法,对吧?也许我忽略了一些简单的事情。

感谢任何建议!

您在上次迭代中遇到错误,因为您正在访问 keys[i + 1]

我正要建议密钥。 Count-1 但我看到你已经提到了它,因此,我建议做一个 if 而不是访问超出范围的索引。

if (i + 1 >= keys.Count)
{
    continue; // or break.. Depends on your logic
}

Key nextKey = keys[i + 1];
// do something with nextKey...

你的错误原因是这个逻辑:

if (keys.Count < i + 1) break;
Key nextKey = keys[i + 1];

如果我们记得数组是从零开始的,并且最大索引比数组的长度少 1,那么就很清楚了。

让我们假装 keys.Count == 10i == 9。由于 10 不小于 9 + 1,因此我们不点击 break 行。但随后我们尝试访问超出数组范围的索引 9 + 1


要解决此问题,我们需要检查在当前密钥之后是否还有另一个密钥可用。由于最大索引是 keys.Count - 1,如果 i 大于或等于该值,我们可以添加一个 break 语句(正如@derHugo 在评论中提到的,i永远不会大于这个值,除非我们在循环中修改它):

for (int i = 0; i < keys.Count; i++)
{
    if (i >= keys.Count - 1) break;
    
    Key nextKey = keys[i + 1];

    // do something with nextKey...
} 

或者我们可以将原始循环索引调整为仅上升到倒数第二个有效索引值,并且我们不必在循环内进行任何额外的检查。这仅在您根本不需要处理最后一项时才有意义:

for (int i = 0; i < keys.Count - 1; i++)
{
    Key nextKey = keys[i + 1];

    // do something with nextKey...
}