ArgumentOutofRangeException

4
Random r = new Random();
        int InvadorNumberA=r.Next(0,5);
        int randomShot = r.Next(5);

        List<Invaders> invadersShooting = new List<Invaders>();
        Invaders invaderA=new Invaders();

        var invaderByLocationX = from invadersSortByLocation in invaders
                                 group invadersSortByLocation by invadersSortByLocation.Location.Y
                                 into invaderGroup
                                 orderby invaderGroup.Key
                                 select invaderGroup;

       invadersShooting = invaderByLocationX.Last().ToList();

     try
       {

           invaderA = invadersShooting[InvadorNumberA];// constantly being thrown there. i cant catch the exception.. so i guess it is being thrown somewhere else. any idea on how i stop it from being thrown?

       }
        catch(ArgumentOutOfRangeException dd)
       {
           invaderA = invadersShooting[0];
       }

堆栈跟踪

" 在 System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) 处引发异常\r\n 在 System.ThrowHelper.ThrowArgumentOutOfRangeException() 处引发异常\r\n 在 System.Collections.Generic.List`1.get_Item(Int32 index) 处引发异常\r\n 在 WindowsFormsApplication1.Game.ReturnFire() 位置 D:\Documents and Settings\Dima\My Documents\Visual Studio 2008\Projects\SpaceInvaders\SpaceInvaders\SpaceInvadorGame\Game.cs:line 444"

目标站点

{Void ThrowArgumentOutOfRangeException(System.ExceptionArgument, System.ExceptionResource)}

更多信息:

{"Index was out of range. Must be non-negative and less than the size of the collection.\r\nParameter name: index"}

{"索引超出范围。必须是非负数且小于集合大小。\r\n参数名: index"}

我通过简单地执行以下操作来解决异常

 invadersShooting = invaderByLocationX.Last().ToList();

           invaderA = invadersShooting[r.Next(0,invadersShooting.Count)];

但我仍然很好奇,异常是在哪里抛出的...嗯

3个回答

9

不要这样做。

异常应该是特殊的。你有各种方法来避免这种特殊情况,而且你一定要这样做。

invaderA = invadersShooting[InvadorNumberA];
invaderA = invadersShooting[0]; 

在第一种情况下,InvadorNumberA 可以是从 0 到 4 的任何数字。在尝试从列表中获取元素之前,请检查并确保该列表至少有 InvadorNumberA + 1 个元素。不要依赖异常来纠正你的操作。或许应该将 InvadorNumberA 约束为 random.Next(0, list.Count)。当列表只有 1 或 2 个元素时,为什么要创建从 0 到 4 的数字呢?

是的,那正是我在看你的答案之前所更改的。我很惊讶地发现try/catch并没有起到帮助的作用... - Dmitry Makovetskiyd
1
通过您的修复,您仍应检查计数。您的列表可能为空。random.Next(0, 0)将返回0(我几乎期望它会失败)。在空列表中,将没有索引为0的元素。请验证! - Anthony Pegram

2

由于无法保证列表的大小至少为1,因此它可能会在catch块中再次抛出。


即使我在 catch 块中删除所有参数,它仍会抛出异常。 - Dmitry Makovetskiyd
可能是Enumerable.Last调用,但在文档中并没有说明它应该抛出ArgumentOutOfRangeException。 - Yet Another Geek
@Dmitry,请将你的IDE设置为在所有异常情况下中断(Ctrl+Alt+E可以让你这样做)。调试代码,看看它发生了什么以及你的输入是什么。索引、列表、计数等。 - Anthony Pegram
你的开发环境没有告诉你异常抛出的位置吗?如果有,请粘贴出来。 - Yet Another Geek
我添加了一些细节并按照你告诉我的做法去做了。 - Dmitry Makovetskiyd

1
如果invadersShooting是空列表,那么在try处理程序中会抛出异常。您将在catch处理程序中捕获此异常。但是,然后您再次索引到空列表中,并且新的异常被抛出,这次是在catch处理程序中。该异常未被捕获,因此您有一个未处理的异常。
在尝试获取元素之前,只需检查invadersShooting.Count即可。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接