0

我目前正在为一个涉及构建“电子宠物”程序的 uni 项目开发一个程序,但是我很早就遇到了一个与我用于存储与每个宠物相关的值的类构造相关的错误记录的一部分。但是,当我跟踪程序时,变量似乎没有初始化,NullReferenceException一旦程序第一次调用变量,它就会抛出一个。关于为什么的任何想法?

static class GlobalVars     // Static class used to store pet values as 'global' variables.
{
    public static TTamagotchiPet Pet1 { get; set; }
    public static TTamagotchiPet Pet2 { get; set; }
    public static TTamagotchiPet Pet3 { get; set; }
    public static TTamagotchiPet Pet4 { get; set; }
}

public void frmTamagotchi_Load(object sender, EventArgs e)      // On Load event; initialises Pet 1.
{
    tmrUpdate.Enabled = true;
    GlobalVars.Pet1.Active = true;
    //GlobalVars.Pet1.Dead = false;
    //GlobalVars.Pet1.FunValue = 0;
    //GlobalVars.Pet1.FoodValue = 0;
    //GlobalVars.Pet1.HealthValue = 0;
    //GlobalVars.Pet1.ExertionValue = 0;
    //GlobalVars.Pet2.Active = false;
    //GlobalVars.Pet3.Active = false;
    //GlobalVars.Pet4.Active = false;
}

private void tmrUpdate_Tick(object sender, EventArgs e)     // Update timer. Each tick reduces pet attributes and checks to see if a pet has died, and controls pet states for the animation timer.
{
// First section updates pet attributes and checks to see if health reaches the 100 limit - at which point the pet dies.
    if (GlobalVars.Pet1.Active == true)  //code crashes here
    {
        if (GlobalVars.Pet1.Dead == false)
        {

frmTamagotchi_load即使这些行未注释,代码也会跳过其余的初始化(我已经在方法中注释掉了许多行);这可能与问题有关吗?

4

6 回答 6

7

您永远不会为宠物本身设置值。

您需要将以下内容放入您的 Load 方法或构造函数中:

GlobalVars.Pet1 = new TTamagotchi();
GlobalVars.Pet2 = new TTamagotchi();
GlobalVars.Pet3 = new TTamagotchi();
GlobalVars.Pet4 = new TTamagotchi();

在您的程序开始时,这些 Pet1...Pet​​4 值为 null,除非您明确实例化它们,否则这些值将保持为 null,如上面的代码中所示。

如果将此代码放在构造函数中,请确保它是static一个,就像GlobalVars一个static类一样。

于 2013-01-02T14:28:08.070 回答
6

您需要以某种方式初始化属性。由于它们没有被设置为任何东西,它们将默认为null,这意味着任何访问成员的尝试都将导致NullReferenceException.

静态构造函数可以解决问题:

static class GlobalVars     // Static class used to store pet values as 'global' variables.
{
    static GlobalVars
    {
      Pet1 = new TTamagotchi();
      Pet2 = new TTamagotchi();
      Pet3 = new TTamagotchi();
      Pet4 = new TTamagotchi();
    }

    public static TTamagotchiPet Pet1 { get; set; }
    public static TTamagotchiPet Pet2 { get; set; }
    public static TTamagotchiPet Pet3 { get; set; }
    public static TTamagotchiPet Pet4 { get; set; }
}
于 2013-01-02T14:28:37.797 回答
2

为什么?因为你没有初始化它。您可以创建一个静态 ctor 并初始化您要使用的所有属性:

static GlobalVars     
{
    // ...
    static GlobalVars()
    {
        Pet1 = new TTamagotchiPet();
        // ...
    }
}
于 2013-01-02T14:26:40.183 回答
1

您已经声明了许多引用类型的类变量。

当您声明一个类变量(无论是静态变量还是实例变量)时,它们被分配到变量的类型在default(T)哪里。T在引用类型(例如class T)的情况下,这是null.

如果您希望将它们初始化为一个值,而不是default(T)您应该在声明点执行赋值:

static class ProbablyNotWhatYouReallyNeed
{
    // assigned something other than the default at declaration
    private static TTomagachiPet _pet1 = new TTomagachiPet();

    // You probably don't want to change the *instance*, but rather you want
    // Access to the instance
    public static TTomagachiPet Pet1 { get { return _pet1; } }
于 2013-01-02T14:30:22.090 回答
0

你需要类似的东西:

static class GlobalVars
{
    public static TTamagotchiPet Pet1 { get; set; }
    static GlobalVars() 
    {
        Pet1 = new TTamagotchiPet();
    }
}
于 2013-01-02T14:28:44.293 回答
0

问题是您从未真正初始化Pet1对象。尝试将此调用添加到您的Load方法中:

tmrUpdate.Enabled = true;
GlobalVars.Pet1 = new TTamagotchiPet();
GlobalVars.Pet1.Active = true;

您不应该遇到NullReferenceExceptionPet1. 显然,您还需要初始化其他 Pet 对象。

于 2013-01-02T14:29:52.490 回答