【问题标题】:C# UWP Index out of range in for loopC# UWP 索引在 for 循环中超出范围
【发布时间】:2018-12-07 17:03:12
【问题描述】:

我正在关注 youtube 上的教程,出于某种原因,即使使用完全相同的代码,我也会遇到异常:

"Index was out of range. Must be non-negative and less than the size of the collection."

我想要做的是,每次我点击屏幕时,i 值应该增加,但事实并非如此。

代码:

变量:

public static float PointX, PointY, PhotonX, PhotonY;

public static List<float> PhotonXPOS = new List<float>();
public static List<float> PhotonYPOS = new List<float>();
public static List<float> Percent = new List<float>();

在构造函数中:

Rect Bounds = ApplicationView.GetForCurrentView().VisibleBounds;

 //Photon location.
 PhotonX = (float)Bounds.Width / 2; //Always at middle.
 PhotonY = (float)Bounds.Height; //Always at bottom.

另一种方法:

private void GameCanvas_Draw(Microsoft.Graphics.Canvas.UI.Xaml.CanvasControl sender, Microsoft.Graphics.Canvas.UI.Xaml.CanvasDrawEventArgs args)
    {
        ///Display Projectiles.
        for (int i = 0; i < PhotonXPOS.Count; i++)
        {
            //Start and end point of a projectile.
            PointX = (PhotonX + (PhotonXPOS[i] - PhotonX) * Percent[i]);
            PointY = (PhotonY + (PhotonYPOS[i] - PhotonY) * Percent[i]);

            //Drawing of the Photons.
            args.DrawingSession.DrawImage(Scaling.Image(Photon), PointX - (25 * ScaleWidth), PointY - (25 * ScaleHeight));

            //Speed.
            Percent[i] += (0.050f * ScaleHeight);

            //If Photon goes out of screen at the top.
            if (PointY < 0f)
            {
                PhotonXPOS.RemoveAt(i);
                PhotonYPOS.RemoveAt(i);
                Percent.RemoveAt(i);
            }
        }           
    }

异常就行了

PointY = (PhotonY + (PhotonYPOS[i] - PhotonY) * Percent[i]);

好像PhotonYPOS[i] 没有增加,而是保持在起始值0,然后i 增加并高于列表本身。

编辑:这是在屏幕上单击时调用的方法(并将项目添加到列表中):

    public void GameCanvas_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
    {
        if(RoundEnded == true)
        {
            GameState = 0;
            Countdown = 6;
            RoundEnded = false;
        }
        else
        {
            //Goes to next level.
            if (GameState == 0)
            {
                //Go to next level.
                GameState += 1;
                //Start round timer.
                RoundTimer.Start();                  
            }
            else if(GameState > 0)
            {
                //Add Photons.
                PhotonXPOS.Add((float)e.GetPosition(GameCanvas).X);
                PhotonXPOS.Add((float)e.GetPosition(GameCanvas).Y);
                Percent.Add(0f);
            }
        }
    }

【问题讨论】:

  • Percent[i] 和 PhotonXPOS 有相同数量的物品吗?
  • 是的,如果你看顶部,它就在 PhotonXPOS 和 PhotonYPOS 下声明:)
  • 在这里获得可复制设置的代码非常少。所以只有我的猜测:第一。百分比是否与PhotonYPOSPhotonXPOS 具有相同的维度(元素计数)?第二个GameCanvas_Draw 在你点击屏幕时被调用?;第三:是否涉及某种线程?这可能是一个竞争条件,其中在 PhotonXPOSPhotonYPOS 的更新(附加元素)之间执行抽奖
  • 1.是百分比具有相同的元素计数。 2. 不,点击屏幕时不会调用它,它只是绘制图像。 3. 完全没有使用线程。
  • 那么您将新元素添加到该列表的逻辑在哪里,因为它们在提供的代码中是空的?

标签: c# list indexing uwp


【解决方案1】:

您迭代PhotonXPOS.Count,但有时您使用PhotonXPOS.RemoveAt(i); 删除,这就是i 超过数组计数的原因。

一种解决方案是反向for (int i = PhotonXPOS.Count; i &gt; 0; i--)

【讨论】:

  • 但是这个条件在每次循环后都会检查,不是吗?它只导致在删除当前元素时跳过下一个元素。
【解决方案2】:

简单的错字 如 cmets 所述:

改变这个 //Add Photons. PhotonXPOS.Add((float)e.GetPosition(GameCanvas).X); PhotonXPOS.Add((float)e.GetPosition(GameCanvas).Y); Percent.Add(0f);

到那个 //Add Photons. PhotonXPOS.Add((float)e.GetPosition(GameCanvas).X); PhotonYPOS.Add((float)e.GetPosition(GameCanvas).Y); Percent.Add(0f);

对于第二个问题:跳过项目,你应该在删除最后一个项目后减少i

示例 之前的列表 1 2 3 4 5 在这种情况下,i 是 2,指向元素 3, 现在你删除元素 2,i 在循环结束时增加到 3,它指向元素 5

列出之后 1 2 4 5 i=3

在这种情况下,从不使用索引为 2 的元素 4。

建议更改:

if (PointY < 0f)
{
    PhotonXPOS.RemoveAt(i);
    PhotonYPOS.RemoveAt(i);
    Percent.RemoveAt(i);
    i--;// in the next loop handle index i again (i-1+1=i)
}

【讨论】:

  • 谢谢你,我已经实现了改变。
猜你喜欢
  • 2019-04-17
  • 2017-08-09
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 2021-09-02
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多