初始化数组后出现空引用异常
Nullreferenceexception after initializing an array
我一直在尝试在 XNA 中制作测试游戏(visual studio 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
}
}
}
如果有人出于任何原因想要整个 class 我可以编辑它,但这是我能找到的所有相关代码。
编辑:堆栈跟踪
Overbox.exe!Overbox.Player.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Microsoft.Xna.Framework.Graphics.Texture2D texture) Line 53 C#
Overbox.exe!Overbox.MediaHandler.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) Line 54 C#
Overbox.exe!Overbox.Program.Main(string[] args) Line 15 C#
一切都应该在那里。
英雄 class:
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);
}
}
}
非常短的游戏循环版本class:
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
个元素。
以后的某个时间,Draw
方法在Player
中被调用。这反过来调用 characterList[0].Draw(spriteBatch, texture)
。由于我们没有覆盖 Hero
中的 Draw
方法,这会调用相同的方法,但在我们的 Hero
实例上。但请记住 Hero
的 characterList
仍然具有 null
值?好吧,这里唯一发生的事情就是调用 characterList[0].Draw(spriteBatch, texture)
,正如我们现在所知,它是在 null
值上调用 Draw
。
这是我对正在发生的事情的猜测。细节可能有所不同,但我想这种事情是根本原因。可以肯定的是,检查异常的堆栈跟踪。您会注意到 Draw
方法的两个框架,让您知道异常发生在对 Draw
.
的递归调用中
我想这个解决方案有一段时间了,但由于组织原因我不想这样做。我所要做的就是将 characterList
移动到主游戏循环 class 并使其成为 public,保证在调用 draw 方法之前对其进行初始化。这确实有效。
我一直在尝试在 XNA 中制作测试游戏(visual studio 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
}
}
}
如果有人出于任何原因想要整个 class 我可以编辑它,但这是我能找到的所有相关代码。
编辑:堆栈跟踪
Overbox.exe!Overbox.Player.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Microsoft.Xna.Framework.Graphics.Texture2D texture) Line 53 C# Overbox.exe!Overbox.MediaHandler.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch) Line 54 C#
Overbox.exe!Overbox.Program.Main(string[] args) Line 15 C#
一切都应该在那里。
英雄 class:
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);
}
}
}
非常短的游戏循环版本class:
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
个元素。
以后的某个时间,Draw
方法在Player
中被调用。这反过来调用 characterList[0].Draw(spriteBatch, texture)
。由于我们没有覆盖 Hero
中的 Draw
方法,这会调用相同的方法,但在我们的 Hero
实例上。但请记住 Hero
的 characterList
仍然具有 null
值?好吧,这里唯一发生的事情就是调用 characterList[0].Draw(spriteBatch, texture)
,正如我们现在所知,它是在 null
值上调用 Draw
。
这是我对正在发生的事情的猜测。细节可能有所不同,但我想这种事情是根本原因。可以肯定的是,检查异常的堆栈跟踪。您会注意到 Draw
方法的两个框架,让您知道异常发生在对 Draw
.
我想这个解决方案有一段时间了,但由于组织原因我不想这样做。我所要做的就是将 characterList
移动到主游戏循环 class 并使其成为 public,保证在调用 draw 方法之前对其进行初始化。这确实有效。