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

Patryk
  • 3,042
  • 11
  • 41
  • 83
  • possible duplicate of [C# (Array of object) object reference not set to an instance of an object](http://stackoverflow.com/questions/9832765/c-sharp-array-of-object-object-reference-not-set-to-an-instance-of-an-object) - see my answer. – DaveShaw Apr 18 '12 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() – Guillaume Apr 18 '12 at 13:10
  • You never created `array[0]`, so how can you set its value to `5`? – David Schwartz Apr 18 '12 at 13:11

6 Answers6

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;
Faraaz Ahmad
  • 99
  • 2
  • 7
Skalli
  • 2,707
  • 3
  • 27
  • 39
  • 1
    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. – Chris Shain Apr 18 '12 at 13:43
  • Whoever downvoted: Care to explain what you don't like about the question and how I can improve it? – Skalli Nov 26 '13 at 07:43
  • 1
    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(); – ggurov Mar 11 '16 at 06:23
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;
Paolo Tedesco
  • 55,237
  • 33
  • 144
  • 193
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).

THX-1138
  • 21,316
  • 26
  • 96
  • 160
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

Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198
1
int[] asd = new int[99];
for (int i = 0; i < 100; i++)
    asd[i] = i;

Something like that?

Conner
  • 30,144
  • 8
  • 52
  • 73
Charp
  • 198
  • 1
  • 2
  • 15
  • 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. :) – Skalli Apr 18 '12 at 13:28
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()
Palec
  • 12,743
  • 8
  • 69
  • 138