初始化数组后出现Nullreferenceexception

本文关键字:Nullreferenceexception 数组 初始化 | 更新日期: 2023-09-27 18:04:23

我一直试图在XNA(visualstudio 2015(中制作一个测试游戏,但每次加载时我都会收到一个NullReferenceException,尽管我确实初始化了它

    namespace Overbox
    {
        public class Player
        {
             private Player[] characterList = new Player[14];
             virtual public void Initialize()
             {
                  //characterList = new Player[14];
                  characterList[0] = new Hero();
                  //for (int i = 0; i <= characterList.Length; i++)
                  //    characterList[i].Initialize();
                  characterList[0].Initialize();
             }
    }
    virtual public void Draw(SpriteBatch spriteBatch, Texture2D texture)
    {
        //for (int i = 0; i <= characterList.Length; i++)
        //{
        //    if (characterList[i].Active)
        //        characterList[i].Draw(spriteBatch, texture);
        //}
        characterList[0].Draw(spriteBatch, texture); //Here the error occurs
    }

   }
}

如果有人出于任何原因想要整个类,我可以编辑它,但这是我能找到的所有相关代码。

编辑:堆栈跟踪

Overbox.exe!Overbox.Player.Draw(Microsoft.Xna.Framework.Graphics.PriteBatch SpriteBatch,Microsoft.Xna.Framework.GGrahics.Texture2D纹理(第53行C#Overbox.exe!Overbox.MediaHandler.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch SpriteBatch(第54行C#

Overbox.exe!Overbox.Program.Main(字符串[]参数(第15行C#

一切都应该在那里。

英雄等级:

    namespace Overbox.Characters
    {
         class Jacketed : Player
         {
         override public void Initialize()
         {
                //Unrelated setting of variables
         }
         public override void Draw(SpriteBatch spriteBatch, Texture2D texture)
         {
                spriteBatch.Draw(texture, PlayerPosition, Color.White);
         }
    }
}

游戏循环类的极短版本:

  public class Game1 : Microsoft.XNA.Framework.Game
  {
        public static Player player;
        //I do load the content which playerTexture requires before anyone asks about it
        private Texture2D playerTexture;

        protected override void Initialize()
        {
               player = new Player();
               player.Initialize();
        }
        protected override void Draw(GameTime gameTime)
        {
               spriteBatch.Begin();
               player.Draw(spriteBatch, playerTexture);
               spriteBatch.End();
        }
  }

初始化数组后出现Nullreferenceexception

private Player[] characterList = new Player[14];

制作一个Player数组,但并不实际构造对象。因此,最终得到的基本上是一个充满空值的数组。

你错过了这样的东西:

public Player()
{
    foreach (var character in characterList)
    {
        character = new Player();
    }
}

这只是一个猜测,但我假设Hero覆盖InitializeDraw中的一个或两个。假设Hero看起来像这样:

class Hero : Player
{
    public override void Initialize()
    {
        // Do some stuff. Don't call base.Initialize()
    }
}

所以我们已经覆盖了Initialize(),但还没有调用base.Initialize()。我们也没有覆盖Draw(),因此在Hero实例上调用Player中的Draw()时将使用。

因此,让我们考虑一下何时构造Player player。然后player.characterList也被创建,但是它的元素是null。接下来,调用player.Initialize(),设置characterList[0] = new Hero()。注意,characterList[0]也有自己的characterList阵列。

接下来要发生的事情是characterList[0].Initialize()。这在Hero中调用了Initialize()覆盖。这不会在Player中调用Initialize(),因此Hero实例中的characterList仍然具有null元素。

将来的某个时间,Player中会调用Draw方法。这反过来又调用characterList[0].Draw(spriteBatch, texture)。由于我们没有重写Hero中的Draw方法,所以这调用了相同的方法,但在我们的Hero实例上。但还记得HerocharacterList仍然有null值吗?这里唯一发生的事情是调用characterList[0].Draw(spriteBatch, texture),正如我们现在所知,它对null值调用Draw

这是我对正在发生的事情的猜测。细节可能各不相同,但我想这类事情是根本原因。为了确定,请检查异常的堆栈跟踪。您将注意到Draw方法的两个帧,让您知道异常发生在对Draw的递归调用中。

我考虑这个解决方案已经有一段时间了,但由于组织原因,我不想这么做。我所要做的就是将characterList移到主游戏循环类中,并将其公开,以保证在调用draw方法之前对其进行初始化。这确实奏效了。