Search code examples
c#for-loopunity-game-engineindexoutofrangeexception

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


So yes, it's a simple IndexOutOfRange exception--don't hate me. BUT, what I'm doing about it should be working, but isn't. I'm using C# in Unity. I would appreciate any and all help!

In the code below, I need to access the next key in the list. If no key is found after [i], then break from the loop. Simple...? For some reason, it's seemingly not doing the check.

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...

 }

I'm sure someone will suggest just doing keys.Count-1 in the for loop, but when I do that, other parts of my script don't work as expected. There has to be another way, right? Maybe I'm overlooking something simple.

Thanks for any advice!


Solution

  • The reason for your error is in this logic:

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

    If we remember that arrays are zero-based, and that the largest index is 1 less then the length of the array, then it becomes clear.

    Let's pretend keys.Count == 10 and i == 9. Since 10 is not less than 9 + 1, we don't hit the break line. But then we try to access the index 9 + 1, which is out of range for the array.


    To fix this, we need to check if there's another key available after the current key. Since the max index is keys.Count - 1, we can just add a break statement if i is greater than or equal to that value (as @derHugo metioned in the comments, i would never be greater than this value unless we modified it inside the loop):

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

    Or we can adjust the original loop index to only go up to the second-to-last valid index value and we don't have to do any additional checks inside the loop. This only makes sense if you don't need to process the last item at all:

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