初始化数组后出现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();
}
}
private Player[] characterList = new Player[14];
制作一个Player数组,但并不实际构造对象。因此,最终得到的基本上是一个充满空值的数组。
你错过了这样的东西:
public Player()
{
foreach (var character in characterList)
{
character = new Player();
}
}
这只是一个猜测,但我假设Hero
覆盖Initialize
和Draw
中的一个或两个。假设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
实例上。但还记得Hero
的characterList
仍然有null
值吗?这里唯一发生的事情是调用characterList[0].Draw(spriteBatch, texture)
,正如我们现在所知,它对null
值调用Draw
。
这是我对正在发生的事情的猜测。细节可能各不相同,但我想这类事情是根本原因。为了确定,请检查异常的堆栈跟踪。您将注意到Draw
方法的两个帧,让您知道异常发生在对Draw
的递归调用中。
我考虑这个解决方案已经有一段时间了,但由于组织原因,我不想这么做。我所要做的就是将characterList
移到主游戏循环类中,并将其公开,以保证在调用draw方法之前对其进行初始化。这确实奏效了。