知道为什么这个静态类没有初始化吗?

本文关键字:初始化 静态类 为什么 | 更新日期: 2023-09-27 17:50:19

我目前正在为一个涉及构建'电子宠物'程序的单一项目编写程序,但是我很早就遇到了一个错误,这个错误与我用于将与每个宠物相关的值存储为记录的一部分的类构造有关。然而,当我跟踪程序时,变量似乎没有初始化,一旦程序第一次调用该变量,就会抛出一个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方法中我已经注释掉了许多行),即使这些行没有注释;这和问题有关吗?

知道为什么这个静态类没有初始化吗?

您从未为宠物本身设置值。

你需要在你的Load方法或构造函数中加入以下内容:

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

在程序开始时,这些Pet1…Pet4值是空的,并且保持空,除非您显式地实例化它们,就像上面的代码一样。

如果将此代码放入构造函数中,请确保它是static类,因为GlobalVarsstatic类。

您需要以某种方式初始化属性。因为它们没有设置为任何值,所以默认为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; }
}

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

static GlobalVars     
{
    // ...
    static GlobalVars()
    {
        Pet1 = new TTamagotchiPet();
        // ...
    }
}

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

当你声明一个类变量时(无论是静态的还是实例的),它们被赋值为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; } }

您需要这样的内容:

static class GlobalVars
{
    public static TTamagotchiPet Pet1 { get; set; }
    static GlobalVars() 
    {
        Pet1 = new TTamagotchiPet();
    }
}

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

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

你不应该在调用Pet1时碰到NullReferenceException。显然,您还需要初始化其他Pet对象。