tags:

views:

85

answers:

6

I am running the following code on an ASP.NET razor page (cshtml) and am suffering the dreaded "Object reference not set to an instance of an object" problem. Could someone help me out with this problem? The code I'm using is below and the line causing the problem is menu[1][0] = "About";

string[][] menu = new string[5][];
menu[0] = new string[2];
// First menu item
menu[0][0] = "Home";
// First menu URL
menu[0][1] = "#";
// Second menu item
menu[1][0] = "About";
// Second menu URL
menu[1][1] = "#";
// Third menu item
menu[2][0] = "Contact";
// Third menu URL
menu[2][1] = "#";
// Fourth menu item
menu[3][0] = "More Info";
// Fourth menu URL
menu[3][1] = "#";
// Fifth menu item
menu[4][0] = "Test";
// Fifth menu URL
menu[4][1] = "#";

Thanks in advance

+1  A: 

You initialise the first array correctly:

menu[0] = new string[2];

but not the rest, for example you also need:

menu[1] = new string[2]; ..and so on.

Hope that helps!

Kieren Johnstone
A: 

You need to initialize each of the sub arrays

menu[0] = new string[2];
menu[1] = new string[2];
//etc..

Otherwise only menu[0] has a two dimensional array to assign to.

Philip Smith
+3  A: 

You have:

menu[0] = new string[2];

But you need to initialize all of the other first-level elements of menu before you use them.

menu[1] = new string[2];
menu[2] = new string[2];
menu[3] = new string[2];
menu[4] = new string[2];

It's worth noting, though, that you don't need to use a jagged array if the number of elements in the second level is consistent. I don't know if this is just a coincidence in your sample data, but you could do:

string menu[,] = new string[5,2];

This would allow you to do something like:

menu[0,0] = "...";
menu[0,1] = "...";
...
menu[4,1] = "...";

And you wouldn't have to initialize every element of the first level to a new array.

Adam Robinson
+6  A: 

You have only initialized the first element in menu. Try a for loop:

for (int i = 0; i < menu.Length; ++i)
{
    menu[i] = new string[2];
}

Alternatively you could write it like this:

string[][] menu =
{
    new string[] {"Home", "#"},
    new string[] {"About", "#"},
    new string[] {"Contact", "#"},
    new string[] {"More Info", "#"},
    new string[] {"Test", "#"}
};

Or use a rectangular array instead:

string[,] menu =
{
    {"Home", "#"},
    {"About", "#"},
    {"Contact", "#"},
    {"More Info", "#"},
    {"Test", "#"}
};

And since your second element is constant perhaps you don't need to store it at all - in this case you could just use a string[].

string[] menu = { "Home", "About", "Contact", "More Info", "Test" };
Mark Byers
If the lengths truly are consistent (which you'd need in order to use a `for` loop), then a square array is more suitable than a jagged array in the first place.
Adam Robinson
@Adam Robinson: Good point - added.
Mark Byers
I can't believe I overlooked the rectangular/jagged array! Thanks for the great answer.
EnderMB
+1  A: 

It's easier to avoid the problem altogether, and create your array like this:

string[,] menu = new string[,] {
    {"Home", "#"},
    // ...
    {"Test", "#"}
};
Thomas
+1  A: 

I'd recommend going with Mark Byers's answer, or else changing your code to use a multidimensional array instead of a jagged one (array of arrays):

string[,] menu = new string[5, 2];
// First menu item
menu[0, 0] = "Home";
// First menu URL
menu[0, 1] = "#";
// Second menu item
menu[1, 0] = "About";
// Second menu URL
menu[1, 1] = "#";
// And so on...

Multidimensional arrays are not always the best solution, but I find they make life easier when you want to make certain you're dealing with a grid of rectangular dimensions (so you don't have to perform checks on each sub-array such as whether it is null, what its length is, etc.).

That said, I also suggest you consider abstracting your menu setup away from such a low-level construct as a string[] array (e.g., consider writing a Menu class as a collection of MenuItem objects that handles this functionality for you).

Dan Tao