如何创建包含100个新对象的数组?

4
我正在尝试这样做:
class point
{
public int x;
public int y;
}

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

以下是错误信息:

对象引用未设置为对象实例。(@ 最后一行)

出了什么问题? :P


可能重复问题: C#(对象数组)对象引用未设置为对象的实例 - 请看我的答案。 - DaveShaw
你可能想使用结构体(值类型)而不是类(引用类型)。除此之外,在循环中使用构造函数实例化类点:array[i] = new point() - Guillaume
你从未创建过 array[0],那么你怎么能将它的值设置为 5 呢? - David Schwartz
6个回答

12

它仅创建了数组,但所有元素都初始化为null。
你需要一个循环或类似的东西来创建你的类的实例。 (在这种情况下,foreach循环不起作用) 例如:

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

array[0].x = 5;

1
补充@Skalli的答案,如果您的Point是一个结构体而不是类(就像BCL中的Point类型一样),那么您就不需要担心这个问题。在数组中使用类时需要“new”,但结构体则不需要。 - Chris Shain
谁给我点了踩:能否解释一下你不喜欢这个问题的原因,以及我如何改进它? - Skalli
1
那不是我的错,但你的例子是错误的。不能分配foreach迭代变量。必须有另一种循环类型:for (int i = 0; i < array.Length; i++) array[i] = new point(); - ggurov

7
当你进行操作时
point[] array = new point[100];

你创建的是一个数组,而不是100个对象。数组中的元素为空。此时,你需要创建每个元素:

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

6
在这种情况下,您可以将class point更改为struct point,这样new point [500]将创建一个初始为0,0的点数组(而不是null的数组)。

1

正如其他答案所解释的那样,您需要在每个数组位置上初始化对象。您可以使用以下方法之一来创建预初始化的数组

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;
}

如果你的类没有无参构造函数,你可以使用类似以下的方式:
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的两种方法版本都很简单,但我认为略微不太高效。


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

类似这样的吗?


如果你要使用索引,最好使用 for (int i=0; i < asd.Length; ++i)。我们不想冒险发生 IndexOutOfRangeException 错误。 :) - Skalli

0
有时候,LINQ非常方便。它可以提高代码的可读性,减少样板和重复代码。缺点是需要额外的内存分配:会创建枚举器,并且ToArray不知道数组大小,因此可能需要多次重新分配内部缓冲区。仅在代码的可维护性比性能更为关键的情况下使用。
using System.Linq;

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接