有什么想法为什么这个静态类没有初始化?

时间:2013-01-02 14:25:43

标签: c# static records

我目前正在开发一个涉及构建'tamagotchi'程序的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方法中注释掉了很多行),即使这些行未被注释;这可能与这个问题有关吗?

6 个答案:

答案 0 :(得分:7)

你永远不会为宠物自己设定值。

您需要在Load方法或构造函数中添加以下内容:

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

在程序开始时,这些Pet1 ... Pet4值为null,除非您显式实例化它们,否则保持不变,如上面的代码所示。

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

答案 1 :(得分:6)

您需要以某种方式初始化属性。由于它们尚未设置为任何内容,因此默认为null,这意味着任何访问成员的尝试都将导致NullReferenceException

static constructor可以解决问题:

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; }
}

答案 2 :(得分:2)

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

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

答案 3 :(得分: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; } }

答案 4 :(得分:0)

您需要以下内容:

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

答案 5 :(得分:0)

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

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

对于NullReferenceException的来电,您不应该遇到Pet1。显然,您还需要初始化其他Pet对象。