0

I tried to get some help earlier and I don't think I provided enough information though I appreciate all the advice.

The goal is simply to add a new instance of the Object Room to an array and print to a list box. When a user attempts to enter a room name that is already in existence it should simply display in the specs for the room that is already in the array.

I keep getting a null reference exception.

Here is my code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace Room_Class
{
    public partial class Form1 : Form
    {
        Room[] roomArray = new Room[20];
        int count = 0;

        public Form1()
        {
            InitializeComponent();
        }

        private void btnAddRm_Click(object sender, EventArgs e)
        {
            double length, width, height;
            if (VerifyRoomName() == true)
            {


                if (txtRmLen.Text == "" || txtRmWid.Text == "" || txtRmHt.Text == "")
                {
                    for (int i = 0; i < roomArray.Length; i++)
                    {
                        if (txtRmName.Text == roomArray[i].getRoomName())
                        {
                            txtRmName.Text = roomArray[i].getRoomName();
                            txtRmLen.Text = roomArray[i].getLength().ToString();
                            txtRmHt.Text = roomArray[i].getCeilingHeight().ToString();
                            txtRmWid.Text = roomArray[i].getWidth().ToString();
                        }
                        else
                        {
                            roomArray[count] = new Room(roomName);
                            count++;
                        }
                    }
                }
                else
                {
                    try
                    {
                        length = double.Parse(txtRmLen.Text);
                        width = double.Parse(txtRmWid.Text);
                        height = double.Parse(txtRmHt.Text);
                        for (int i = 0; i < roomArray.Length; i++)
                        {
                            if (txtRmName.Text == roomArray[i].getRoomName())
                            {
                                txtRmName.Text = roomArray[i].getRoomName();
                                txtRmLen.Text = roomArray[i].getLength().ToString();
                                txtRmHt.Text = roomArray[i].getCeilingHeight().ToString();
                                txtRmWid.Text = roomArray[i].getWidth().ToString();
                            }
                            else
                            {
                                roomArray[count] = new Room(roomName, length, width, height);
                                count++;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message + "\n\nPlease Enter Valid Values", "Error!");
                    }
                }  
                PrintList();
            }

        }


        private void PrintList()
        {
            double paintTotal = 0, feetTotal = 0;
            string RoomName;
            lstRoomList.Items.Clear();
            for (int i = 0; i < count; i++)
            {
                RoomName = roomArray[i].getRoomName() + "\t" + roomArray[i].SquareFeet().ToString("n1") + "\t" + roomArray[i].GallonsPaint().ToString("n1");
                lstRoomList.Items.Add(RoomName);
                paintTotal += roomArray[i].GallonsPaint();
                feetTotal += roomArray[i].SquareFeet();
                lblTtlGallons.Text = paintTotal.ToString("n1");
                lblTtlSqFt.Text = feetTotal.ToString("n1");
            }
        }

        private bool VerifyRoomName()
        {
            if (roomName == "")
            {
                MessageBox.Show("Please Enter a Room Name", "Error!");
                return false;
            }
            else
                return true;
        }
    }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
user2101459
  • 579
  • 2
  • 8
  • 19
  • where is the exception? – John3136 Feb 27 '13 at 02:08
  • 3
    Welcome to Stack Overflow! Almost all cases of `NullReferenceException` are the same. Please see "[What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)" for some hints. – John Saunders Feb 27 '13 at 02:08

3 Answers3

5

Your code should be

if (roomArray[i] != null)

Whenever you create an array, you'll have to initialize it's individual items before you can access them.

Room[] roomArray = new Room[20];

roomArray[0] = new Room();
scartag
  • 17,548
  • 3
  • 48
  • 52
  • was about to give same answer but then found out that OP is initializing `roomArray` in likes of this part `roomArray[count] = new Room(roomName);` // though having it in else part is suspicious – exexzian Feb 27 '13 at 02:13
  • @Bingo Yeah i saw that too... i just figure his biggest problem is probably understanding how to use arrays in general, hence my answer :) – scartag Feb 27 '13 at 02:15
3

Because the elements of Room inside Room[] we're not initialized.

Try

public Form1()
{
    InitializeComponent();
    for(int i = 0; i < roomyArray.Length; i++) roomArray[i] = new Room();
}
Freddie Fabregas
  • 1,162
  • 1
  • 7
  • 17
1

As the other answers have said, you need to initialize the array before you start using it. When you write:

Room[] roomArray = new Room[20];

What you are telling the computer to do is reserve you enough memory for references to 20 objects of the type Room. The other solutions proposed are fine, but if you want performance, try the following:

According to this SO answer, using the following function would be more performant than the other solutions provided thus far. This also has supporting evidence from this blog post.

Note: I've converted to use generics

    /// <summary>
    /// Fills an array with a default value
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="array">The array to fill with a default value</param>
    /// <param name="value">The default value</param>
    public static void MemSet<T>(T[] array, T value)
    {
        if (array == null)
        {
            throw new ArgumentNullException("array");
        }

        int block = 32, index = 0;
        int length = Math.Min(block, array.Length);

        //Fill the initial array
        while (index < length)
        {
            array[index++] = value;
        }

        length = array.Length;
        while (index < length)
        {
            Buffer.BlockCopy(array, 0, array, index, Math.Min(block, length - index));
            index += block;
            block *= 2;
        }
    }

Usage

Memset<Room>(roomArray, new Room());
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
Stuart Blackler
  • 3,732
  • 5
  • 35
  • 60