4

I'm trying something like that:

class point
{
public int x;
public int y;
}

point[] array = new point[100];
array[0].x = 5;

and here's the error: Object reference not set to an instance of an object. (@ the last line)

whats wrong? :P

3
  • possible duplicate of C# (Array of object) object reference not set to an instance of an object - see my answer. Commented Apr 18, 2012 at 13:08
  • You may want to use a struct (value type) instead of class (references). Other than that, instanciate the class point in a loop using the constructor : array[i] = new point() Commented Apr 18, 2012 at 13:10
  • You never created array[0], so how can you set its value to 5? Commented Apr 18, 2012 at 13:11

6 Answers 6

12

It only creates the array, but all elements are initialized with null.
You need a loop or something similar to create instances of your class. (foreach loops dont work in this case) Example:

point[] array = new point[100];
for(int i = 0; i < 100; ++i)
{
    array[i] = new point();
}

array[0].x = 5;
Sign up to request clarification or add additional context in comments.

3 Comments

To add to @Skalli's answer here, if your Point were a struct instead of a class (as the Point type is in the BCL), then you wouldn't need to worry about this. Class's need to be "new'd" when used in arrays, structs don't.
Whoever downvoted: Care to explain what you don't like about the question and how I can improve it?
That was not me, but your example is incorrect. One cannot assign foreach iteration variable. There have to be another loop type: for (int i = 0; i < array.Length; i++) array[i] = new point();
7

When you do

point[] array = new point[100];

you create an array, not 100 objects. Elements of the array are null. At that point you have to create each element:

array[0] = new point();
array[0].x = 5;

Comments

6

You can change class point to struct point in that case new point[500] will create an array of points initialized to 0,0 (rather than array of null's).

Comments

1

As the other answers explain, you need to initialize the objects at each array location. You can use a method such as the following to create pre-initialized arrays

T[] CreateInitializedArray<T>(int size) where T : new()
{
    var arr = new T[size];
    for (int i = 0; i < size; i++)
        arr[i] = new T();
    return arr;
}

If your class doesn't have a parameterless constructor you could use something like:

T[] CreateInitializedArray<T>(int size, Func<T> factory)
{
    var arr = new T[size];
    for (int i = 0; i < size; i++)
        arr[i] = factory();
    return arr;
}

LINQ versions for both methods are trivial, but slightly less efficient I believe

Comments

1
int[] asd = new int[99];
for (int i = 0; i < 100; i++)
    asd[i] = i;

Something like that?

1 Comment

If you are going to use an index, you better use for (int i=0; i < asd.Length; ++i)We don't want to risk an IndexOutOfRangeException. :)
0

Sometimes LINQ comes in handy. It may provide some extra readability and reduce boilerplate and repetition. The downside is that extra allocations are required: enumerators are created and ToArray does not know the array size beforehand, so it might need to reallocate the internal buffer several times. Use only in code whose maintainability is much more critical than its performance.

using System.Linq;

const int pointsCount = 100;
point[] array = Enumerable.Range(0, pointsCount)
    .Select(_ => new point())
    .ToArray()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.