【问题标题】:Argument out of range exception参数超出范围异常
【发布时间】:2012-04-22 14:32:50
【问题描述】:

谁能告诉我为什么会出现这个异常?好吧,我知道“为什么”我得到它是因为它说我尝试访问的列表中的元素不存在,但是单步执行代码我可以看到它确实存在?

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

在我实例化 CalculationHelper calcHelper 类的 Game1 类中,然后调用其中一个类方法。 首先,在 Game1 中,我在 for() 循环中调用 calcHelper.ForceVanishingPointIntersections(...) 方法,如下所示。这工作得很好, calcHelper.ForceVanishingPointIntersections(...) 方法将值添加到 CalculationHelper 类中的 IntersectionPointList (参见下面的方法)。

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 返回指定点 (i) 处的值) 公共 Vector2 GetIntersectionPointListElementAt(int index) { Vector2 结果 = 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 个值。我正在尝试访问第二个值。

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

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

【问题讨论】:

    标签: c# exception xna


    【解决方案1】:

    因为您使用索引i + 1 访问LineList[],所以您必须在for 条件中将最后一个索引减1。 (注意-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 的 cmets,第二种方法是正确的。

    删除循环内的i++,这非常罕见且令人困惑。而是将其替换为循环头中的i += 2

    还要注意(再次根据 Chris Gessler 的说法)IntersectionPointList 的项目数量是 LineList 的一半。因此用i / 2 调用GetIntersectionPointListElementAt。因为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);
    }
    

    【讨论】:

    • 您是否看到 OP 在循环底部有一个额外的 i++?这不是实现这一点的最佳方法,但它确实将最后一个索引减少了 1。
    • 我没看到,抱歉。它在每个循环中将索引增加 2;但是,它不会将最后一个索引减少 1!仍然需要将条件更改为i &lt; LineList.Count - 1
    • 非常正确...但还要注意,直到 GetIntersectionPointListElementAt 才会发生错误。在我看来,LineList 集合的项目数是 IntersectionPointList 集合的两倍,但 OP 只是从 LineList 集合中传入索引 i。
    • 在这种情况下,调用必须更改为GetIntersectionPointListElementAt(i/2)
    • 感谢那些家伙一百万。工作了一个款待。从来不知道你可以在 for 循环中声明 2 个值(i 和 k)。将来它会派上用场。你每天都会学到新东西
    【解决方案2】:
    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。

    【讨论】:

      【解决方案3】:

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

      您应该将 LineList 集合更改为List&lt;Tuple&lt;string,string&gt;&gt;,这样每个项目就有两行与每个 Sprite 对齐。这将在 Lines 和 Sprites 之间创建一对一的关系。

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

      【讨论】:

      • +1。好点,非常感谢您的建设性cmets。
      猜你喜欢
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多