参数超出范围异常

时间:2012-04-22 14:32:51

标签: c# exception xna

有谁能告诉我为什么我得到这个例外?我知道“为什么”我得到它是因为它说我试图访问的列表中的元素不存在,但是通过代码我可以看到它确实存在吗?

在Game1中,我调用了一个帮助类的计算方法。然后,当计算完成时,我将结果添加到List<>在CalculationHelper类中。 这个代码如下:

在Game1类中,我已经实现了CalculationHelper calcHelper类,然后调用其中一个类方法。 Fisrt,在Game1中我在for()循环中调用calcHelper.ForceVanishingPointIntersections(...)方法,如下所示。这很好用,并且calcHelper.ForceVanishingPointIntersections(...)方法将值添加到IntersectionPointList<>在CalculationHelper类中(参见下面的方法)。

for (int i = 0; i < LineList.Count; i++)
{
    calcHelper.ForceVanishingPointIntersections(LineList[i], LineList[i + 1]);

    AddSprite(VanishingPointIntersectionList, calcHelper.GetIntersectionPointListElementAt(i), greenCirlce);
    i++;
}

要做一些计算并在CalculationHelper类的IntersectionPointlist中添加一个值,我会这样做:

List<Vector2> IntersectionPointList = new List<Vector2>();
public void ForceVanishingPointIntersections(Line line1, Line line2)
{
    Vector2 intersectionPoint;
    // Do some calculations

    IntersectionPointList.Add(intersectionPoint);
}

最后在Game1类中,for()循环中的第二个方法我调用AddSprite来创建一个Sprite。我想传递CalculationHelper类IntersectionPointList中存储的值作为Sprite的坐标。 为此,我调用了calcHelper.GetIntersectionPointListElementAt(i),它调用CalculationHelper类中的方法,如此(它应该从IntersectionPointList&lt;&gt;返回指定点(i)的值)         public Vector2 GetIntersectionPointListElementAt(int index)         {             Vector2 result = this.IntersectionPointList [index];             返回结果;         } 第一次执行for()循环时,这很好。我进行计算,值存储在列表中,我可以从列表中获取此值并将其传递给AddSprite(..)。但是,第二次绕过for()循环,当我从AddSprite()方法调用GetIntersectionPointListElementAt时,我在

中得到一个异常
public Vector2 GetIntersectionPointListElementAt(int index)
{
    Vector2 result = this.IntersectionPointList[index];    // Exception thrown here
    return result;
}

说索引超出了范围?但是通过代码,我的IntersectionPointList会更新,它会显示列表现在包含2个值。而我正在尝试访问第二个值。

有谁知道为什么会这样? 对于我的生活,我无法弄清楚我哪里出错了。

如果需要更多代码,我可以发布更多代码,请告诉我

3 个答案:

答案 0 :(得分:3)

因为您使用索引LineList[]访问i + 1,所以您必须在for-condition中将最后一个索引减一。 (注意-1

for (int i = 0; i < LineList.Count - 1; i++) {
    calcHelper.ForceVanishingPointIntersections(LineList[i], LineList[i + 1]);
    AddSprite( ... );
}

这将使用索引

调用ForceVanishingPointIntersections
(0, 1), (1, 2), (2, 3), ... (Count-2, Count-1)

请注意,LineList的索引范围为0 ... Count-1


如果需要非重叠索引,例如

(0, 1), (2, 3), (4, 5), ... (Count-2, Count-1)

然后将循环更改为

for (int i = 0; i < LineList.Count - 1; i += 2) {
    calcHelper.ForceVanishingPointIntersections(LineList[i], LineList[i + 1]);
    AddSprite(
        VanishingPointIntersectionList,
        calcHelper.GetIntersectionPointListElementAt(i / 2),
        greenCirlce);
}

编辑根据Chris Gessler的评论,第二种方法是正确的。

删除循环中的i++,这是非常罕见和令人困惑的。相反,请在循环标题中将其替换为i += 2

另请注意(再次根据Chris Gessler的说法)IntersectionPointList的项目数量是LineList的一半。因此,请GetIntersectionPointListElementAti / 2联系。由于i{0, 2, 4, ... }i / 2{0, 1, 2, ...}


for循环允许您在第一和第三部分中使用逗号分隔的语句列表。您可以使用它来维护两个索引

for (int i = 0, k = 0; i < LineList.Count - 1; i += 2, k++) {
    calcHelper.ForceVanishingPointIntersections(LineList[i], LineList[i + 1]);
    AddSprite(
        VanishingPointIntersectionList,
        calcHelper.GetIntersectionPointListElementAt(k),
        greenCirlce);
}

答案 1 :(得分:1)

for (int i = 0; i < LineList.Count; i++)
{
    calcHelper.ForceVanishingPointIntersections(LineList[i], LineList[i + 1]);

    ...

    i++;
}

而不是这样做,你应该这样做:

for (int i = 0; i < LineList.Count; i += 2)
{
    calcHelper.ForceVanishingPointIntersections(LineList[i], LineList[i + 1]);

    ...
}

如果LineList.Count不均匀,例如:3。 它将从0开始,你使用0和1。 然后它跳到2,你使用2和3。 但是哎呀!没有3个! 只算3! 0到2!

多数人,你会得到超出范围异常的争论。 为了避免这种情况,你可以检查Count%2 == 0,或者你可以直到LineList.Count - 1,如果你不介意跳过额外的,如果有的话。

答案 2 :(得分:1)

看起来你每个Sprite都要添加两行。索引不会排队。当LineList有10个项目时,您将只有5个IntersectionPointList项目,因此传入9的索引将失败。

您应该将LineList集合更改为List<Tuple<string,string>>,以便每个项目有两行,这些行将与每个Sprite对齐。这将在Lines和Sprites之间创建一对一的关系。

我想你总是可以传入一个索引(i / 2),它应该是每两行正确的Sprite。