Reputation: 2452
I am trying to make a 1d array of lists. I make it like this:
public static List<string>[] words = new List<string>[30];
public static List<string>[] hints = new List<string>[30];
And I call it like this:
foreach (string item in vars.directory)
{
reader2 = new StreamReader(item);
while (reader2.Peek() > 0)
{
string line = reader2.ReadLine();
if (line.StartsWith("#"))
{
vars.words[counter].Add(line.Substring(1, line.Length - 1)); //here
}
else if (line.StartsWith("-"))
{
vars.hints[counter].Add(line.Substring(1, line.Length - 1)); //another here
}
else if (line == "@end")
{
counter++;
}
}
}
I just wanted to add that vars is where I keep my public variables and that counter is indeed at 0 when the loop starts.
EDIT In my haste I forgot to add the question... oops...
Here it is: When I call the add function (or any another function for that matter) it returns a null reference exception. How can I fix this?
Upvotes: 1
Views: 5604
Reputation: 18664
You could initialize the lists right before you use them:
foreach (string item in vars.directory)
{
reader2 = new StreamReader(item);
while (reader2.Peek() > 0)
{
string line = reader2.ReadLine();
// new code
if (vars.words[counter] == null) vars.words[counter] = new List<string>();
if (vars.hints[counter] == null) vars.hints[counter] = new List<string>();
if (line.StartsWith("#"))
{
vars.words[counter].Add(line.Substring(1, line.Length - 1)); //here
}
else if (line.StartsWith("-"))
{
vars.hints[counter].Add(line.Substring(1, line.Length - 1)); //another here
}
else if (line == "@end")
{
counter++;
}
}
}
Upvotes: 0
Reputation: 59111
The problem is that array values are initialized to the default value, and the default value for reference types is null
.
default(List<string>)
returns null
.
So, you'll need to re-initialize the objects in the array before you can access them, otherwise you will get a NullReferenceException
.
One way to initialize all the objects in your array up front is to use this Linq statement:
const int sizeOfLists = 5;
List<string>[] lists = Enumerable.Range(0, sizeOfLists)
.Select(i => new List<string>())
.ToArray();
Another option is to initialize and add the sub-lists only when you need them, by using an outer List:
var lists = new List<List<string>>();
// ...
var aSubList = new List<string>();
lists.Add(aSubList);
This is particularly useful if you don't know the size of the outer set of lists up-front, and is still accessible by index.
(This was a comment before, but I made it an answer since many other answers got caught up in the solution and don't describe the problem)
Upvotes: 0
Reputation: 1204
I assume you're crashing when attempting to call .Add
on your array element. You need to initialize your arrays with valid objects.
for( Int32 i = 0; i < vars.words.Length; ++i )
vars.words[i] = new List<string>();
for( Int32 i = 0; i < vars.hints.Length; ++i )
vars.hints[i] = new List<string>();
Upvotes: 7
Reputation: 8150
Using a list of lists, as already recommended, would make you escape your problems, and it´s much more flexible and handy than your construction.
-> f.i. if the size of your data changes, you don´t have to change the list size, but the array
Upvotes: 2
Reputation: 26782
Here's a one-liner to initialize an array of lists of size 30:
static List<string>[] lists = (from i in Enumerable.Range(0, 30)
select new List<string>()).ToArray();
Upvotes: 0
Reputation: 15242
Why not just make a List<List<string>>
, but yes you can make an array of lists
Upvotes: 6