Object reference not set to an instance of an object

Started by
8 comments, last by WozNZ 7 years, 12 months ago

I'm having this problem in Unity when trying to initialize a few variables. I have an example below.

public class PlanetDetails
{
private int planetID;
private string planetName;

public int PlanetID
{
get { return planetID; }
set { planetID = value; }
}

public string PlanetName
{
get { return planetName; }
set { planetName = value; }
}
}

PlanetDetails[] Planet = new PlanetDetails[10];

...

Planet.PlanetID = (System.SystemID + Random.Range(0, 1000));
Planet.PlanetName = "Test" + i;
Debug.Log(Planet.PlanetID);
Debug.Log(Planet.PlanetName);

When I try to initialize a variable, it gives me an error in Unity, and since I'm pretty new to programming, I can't understand why. Any help would be great.

Advertisement

What is the exact error message, and what line is it on?


Planet[i] = new PlanetDetails();
You can only skip that step if you're using an array of value types (int, bool, float, enum, struct - basically everything that's not a class).

When you make an array, its entries are all set to the "default" value of the corresponding type.

int: 0
float: 0.0f
double: 0.0
all the other numeric and enum types = whatever their concept of 0 is.
bool: false
class: null
struct: non-null, each individual field = its own default

In this case you have a class, so the default is null; You need to individually 'new' each element in the array.

What is the exact error message, and what line is it on?

NullReferenceException: Object reference not set to an instance of an object
GameGUISystemDetails.Start () (at Assets/Scripts/GameGUISystemDetails.cs:157)

The line is this: Planet.PlanetID = (System.SystemID + Random.Range(0, 1000));

If I comment this line, the warning will go to the next line, which is the initialization of Planet.PlanetName and so on.

So the problem is that you are expecting the elements of the array to be there, but they're not. You're only allocating the space for the elements in your array, you then need to put something there.


PlanetDetails[] Planet = new PlanetDetails[10];
for(int i=0; i<10;i++)
  Planet[i]=new PlanetDetails();

Cheers,

Bob


[size="3"]Halfway down the trail to Hell...

So the problem is that you are expecting the elements of the array to be there, but they're not. You're only allocating the space for the elements in your array, you then need to put something there.


PlanetDetails[] Planet = new PlanetDetails[10];
for(int i=0; i<10;i++)
  Planet[i]=new PlanetDetails();

:D Thank you, I completely forgot about that ...

The Linq based solution is below, I prefer as less "moving parts" to screw up :)

PlanetDetails[] Planet = Enumerable.Repeat(0, 10).Select(_ => new PlanetDetails()).ToArray();

I am using _ as the select variable passed in as it is not used

As a follow up, in the above Range and Repeat are interchangeable given we are not using the value in _

var Planet = Enumerable.Repeat(0, 10).Select(_ => new PlanetDetails()).ToArray();

=

var Planet = Enumerable.Range(0, 10).Select(_ => new PlanetDetails()).ToArray();

There is a more subtle use of repeat

Func<PlanetDetails> buildPlanet = () => new PlanetDetails();

var Planet = Enumerable.Repeat(buildPlanet, 10).Select(build => build()).ToArray()

This returns the same planet factory 10 times, we then call the builder in each case and slot the results into an array

:)

Just curious: My C# is rusty, but isn't there anything like this?

private static IEnumerable<T> Generate(Func<T> f) {
    while (true) yield return f();
}

Used like so:

var Planets = Generate(() => new PlanetDetails()).Take(10).ToArray();

Feels a bit more straightforward than WozNZ's suggestions.

Just curious: My C# is rusty, but isn't there anything like this?


private static IEnumerable<T> Generate(Func<T> f) {
    while (true) yield return f();
}
Used like so:


var Planets = Generate(() => new PlanetDetails()).Take(10).ToArray();
Feels a bit more straightforward than WozNZ's suggestions.

Nice one, very explicit. For some reason I forgot about using a generator

This topic is closed to new replies.

Advertisement