77

I have a very beginning C# question. Suppose I have a class called GameObject, and I want to create an array of GameObject entities. I could think of writing code like:

GameObject[] houses = new GameObject[200];

The compiler complains (assuming because of invalid syntax). Since this is XNA development, I load my texture in the LoadContent() method as follows:

 houses[0].Model = Content.Load<Model>("Models\\Building_01 Windowed");

where houses[0] should be a GameObject and can be loaded like this, but the compiler throws this error:

"Use the "new" keyword to create an object instance"

"Check to determine if the object is null before calling the method"

There must be something wrong with my initialization.

5
  • 3
    Apart from your spacing, there's nothing wrong with that. Tell us the specific error? Commented Jul 21, 2010 at 16:42
  • 5
    The compiler did not tell you something is wrong. The compiler gave you a specific error message or messages. Edit your question to include the specifics. Commented Jul 21, 2010 at 16:43
  • 2
    Well fix the something then coz I can't read your compiler's mind. How can you possible expect any viable answers to such a question? Commented Jul 21, 2010 at 16:43
  • Are you sure the compiler error was on that line? It should have given a line number along with the error Commented Jul 21, 2010 at 16:49
  • why not make a list of game objects instead of an array... I think lists are better for reference types Commented Jul 21, 2010 at 16:55

9 Answers 9

93

The issue here is that you've initialized your array, but not its elements; they are all null. So if you try to reference houses[0], it will be null.

Here's a great little helper method you could write for yourself:

T[] InitializeArray<T>(int length) where T : new()
{
    T[] array = new T[length];
    for (int i = 0; i < length; ++i)
    {
        array[i] = new T();
    }

    return array;
}

Then you could initialize your houses array as:

GameObject[] houses = InitializeArray<GameObject>(200);
Sign up to request clarification or add additional context in comments.

3 Comments

Very good helper,Thanks,Dan. I sort of briandeaded when I was creating the array. But I still feel the compiler of such modern languges should be cleverer.
@Robert: You do not always want to initialize all the objects.
and make it static and in a static class so it is handy everywhere
25

For people still looking

    Object[] obj = {
        new() { key = "key", value = "value"},
        new() { key = "key", value = "value"},
        new() { key = "key", value = "value"},
        new() { key = "key", value = "value"}
    };

1 Comment

could you take the final comma out pls? Thanks!
20

With LINQ, you can transform the array of uninitialized elements into a new collection of created objects with one line of code:

var houses = new GameObject[200].Select(h => new GameObject()).ToArray();

Actually, you can use any other source for this, even generated sequence of integers:

var houses = Enumerable.Repeat(0, 200).Select(h => new GameObject()).ToArray();

However, the first solution seems more readable to me, although the type of the original sequence is not important.

2 Comments

I actually think the second case is much more readable and obvious what it's doing... and like you said, in the first example the type of the original sequence is not important, which is very confusing for anyone reading it. Just a warning to anyone else using this though, Enumerable.Repeat can have some performance implications if you writing performance critical code. If you're not then I think this is a great solution.
That’s a good point! The second case is more correct as you described, but in the first one you can “guess” a purpose of the line from the very beginning.
15

You are creating an array of null references. You should do something like:

for (int i = 0; i < houses.Count; i++)
{
    houses[i] = new GameObject();
}

4 Comments

Should be houses.Length instead of houses.Count.
Oops! I don't use arrays - why would you? I use some kind of collection. Collections have a Count property.
Because arrays will be faster in some situations.
I'd love to hear about those situations.
1

I guess GameObject is a reference type. Default for reference types is null => you have an array of nulls.

You need to initialize each member of the array separatedly.

houses[0] = new GameObject(..);

Only then can you access the object without compilation errors.

So you can explicitly initalize the array:

for (int i = 0; i < houses.Length; i++)
{
    houses[i] = new GameObject();
}

or you can change GameObject to value type.

1 Comment

You still haven't demonstrated how he declares the houses array in the first place.
1

you need to initialize the object elements of the array.

GameObject[] houses = new GameObject[200];

for (int i=0;`i<house` i<houses.length; i++)
{ houses[i] = new GameObject();}

Of course you initialize elements selectively using different constructors anywhere else before you reference them.

Comments

0

The reason this is happening is because initializing an array does not initialize each element in that array. You need to first set houses[0] = new GameObject() and then it will work.

1 Comment

Except that he still has to first create the houses array, which he hasn't been able to do yet.
-1

Everything you have looks fine.

The only thing I can think of (without seeing the error message, which you should have provided), is that GameObject needs a default (no parameter) constructor.

1 Comment

It shouldn't need a parameterless constructor in order to declare a simple array. It doesn't initialize it with actual instances, but rather null.
-1

My answer, which is based on Eugene's, would have been

var houses = Enumerable.Repeat(new GameObject(), 200).ToArray()

1 Comment

In this case: one gameobject in whole array

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.