0

I'm currently working on a program for a uni project that involves building a 'tamagotchi' program, but I've run across an error quite early on related to the class construct I've used for storing the values related to each pet as part of a record. However, when I trace the program, the variables do not appear to initialize and it throws up a NullReferenceException once the program calls the variable for the first time. Any ideas on why?

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)
        {

The code also skips out the rest of the initialization (where I've commented out numerous lines in the frmTamagotchi_load method) even when the lines are uncommented; could this be related to the issue?

svick
  • 236,525
  • 50
  • 385
  • 514
  • You have a bunch of static properties that have never been initialized - they are all `null`. – Oded Jan 02 '13 at 14:27
  • 4
    [What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net) See the "Indirect" case. – dtb Jan 02 '13 at 14:27

6 Answers6

7

You never set the values for the pets themselves.

You need to put the following in your Load method or your constructor:

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

At the start of your program, these Pet1...Pet4 values are null, and remain so unless you explicitly instantiate them, as in the code above.

If you put this code in a constructor, make sure it is a static one, as GlobalVars is a static class.

Roy Dictus
  • 32,551
  • 8
  • 60
  • 76
  • Ah, thanks. I knew it'd be something insanely stupid, but I've not had that much experience in C based languages. – user1943107 Jan 02 '13 at 14:39
  • 1
    If a constructor, it need to be the _static_ constructor, not an instance constructor. – Oded Jan 02 '13 at 14:40
6

You need to initialize the properties somehow. As they have not been set to anything, they will default to null, meaning any attempt to access a member will result in a NullReferenceException.

A static constructor would do the trick:

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; }
}
Oded
  • 489,969
  • 99
  • 883
  • 1,009
2

Why? Because you didn't initialize it. You can create a static ctor and initialize all of the properties you want to use:

static GlobalVars     
{
    // ...
    static GlobalVars()
    {
        Pet1 = new TTamagotchiPet();
        // ...
    }
}
tukaef
  • 9,074
  • 4
  • 29
  • 45
1

You have declared many class variables that are reference types.

When you declare a class variable (be it static or instance) they are assigned default(T) where T is the type of the variable. In the case of reference types (e.g. class T) this is null.

If you would like these to be initialized to a value other than default(T) you should perform an assignment at the point of declaration:

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; } }
user7116
  • 63,008
  • 17
  • 141
  • 172
  • Wouldn't it be better for a beginner to talk about "the default value of a type", instead of confusing them with `default(T)`? – svick Jan 02 '13 at 14:33
  • Possibly, at some point they'll ask, "how do I get the default value of a type?" It would probably be simpler to have said, "just put a `new TTomagotchiPet()` before setting any values," but that wouldn't have explained why they had a problem. – user7116 Jan 02 '13 at 14:44
0

You need something like:

static class GlobalVars
{
    public static TTamagotchiPet Pet1 { get; set; }
    static GlobalVars() 
    {
        Pet1 = new TTamagotchiPet();
    }
}
Robert Levy
  • 28,747
  • 6
  • 62
  • 94
0

The problem is that you never actually initialize the Pet1 object. Try adding this call into your Load method:

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

You shouldn't run into the NullReferenceException for calls to Pet1. Obviously, you would need to initialize the other Pet objects too.

Sean Kornish
  • 808
  • 8
  • 11