20
public class Sample
{
     static int count = 0;
     public int abc;
     public Sample()
     {
        abc = ++Sample.count;
     }
}

我想创建一个上述类的数组,并希望通过调用默认构造函数来初始化数组中的每个元素,以便每个元素可以有不同的abc. 所以我这样做了:

Sample[] samples = new Sample[100];

但这并没有做我认为应该做的事情。似乎这样默认构造函数没有被调用。创建数组时如何调用默认构造函数?

我也想知道上面的语句是做什么的?

4

6 回答 6

46

你不能,基本上。当你创建一个数组时,它最初总是用类型的默认值填充——对于一个类来说,它总是一个空引用。因为int它是 0,因为bool它是假的,等等。

(如果你使用数组初始化器,那将创建“空”数组,然后用你指定的值填充它,当然。)

通过调用构造函数来填充数组的方法有很多种——我自己可能只使用一个 foreach 循环。使用带有 Enumerable.Range/Repeat 的 LINQ 感觉有点勉强。

当然,您始终可以编写自己的填充方法,甚至作为扩展方法:

public static T[] Populate<T>(this T[] array, Func<T> provider)
{
    for (int i = 0; i < array.Length; i++)
    {
        array[i] = provider();
    }
    return array;
}

然后你可以使用:

Sample[] samples = new Sample[100].Populate(() => new Sample());

我喜欢这个解决方案的地方:

  • 它仍然是一个表达式,可以在各种场景中使用
  • 它不会引入您实际上不想要的概念(例如重复单个值或创建范围)

当然,您可以添加更多选项:

  • 采用 aFunc<int, T>而不是 a的重载,Func<T>将索引传递给提供者
  • 创建数组并填充它的非扩展方法
于 2011-01-29T21:19:19.957 回答
9

您的代码仅创建数组,但不创建任何项目。基本上,您需要将的实例存储Sample 到此数组中。

简单地说,没有任何花哨的 LINQ 等:

Sample[] samples = new Sample[100];
for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();

另请注意,您的解决方案不是线程安全的。

于 2011-01-29T21:19:01.857 回答
4

无法自动执行此操作;数组初始化本质上是“将这块内存擦除为 0”。您必须执行以下操作:

var arr = new SomeType[size];
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
于 2011-01-29T21:18:58.073 回答
2

问题是通过声明该数组,您从未为每个对象分配空间。您只是为 100 个 Sample 类型的对象分配了空间。您必须自己调用每个构造函数。

详细说明:

Food[] foods = Food[100];
for (int k = 0; k < foods.length; k++) {
   foods[k] = new Food();
}

一个有趣的解决方法可能是工厂函数。考虑将此附加到您的 Sample 类。

public static Sample[] getInstances(int aNumber) {
    Sample[] sample = Sample[aNumber];
    for (int k = 0; k < sample.length; k++) {
       sample[k] = new Sample();
    }

    return sample;
}

隐藏瑕疵 - 提供这对您有用的功能。

于 2011-01-29T21:19:03.170 回答
2

此时您有一个大小为 100 的空数组,如果您想用项目填充它,那么您必须执行以下操作:

for(int i=0; i<samples.Length; i++) {
   samples[i] = new Sample();
}
于 2011-01-29T21:24:15.217 回答
1

这是另一个不需要任何扩展方法的单行:

Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();

另一个不错的选择是斯科特乔恩回答的建议:

public static T[] Populate<T>(this T[] array) 
    where T : new()
{
    for (int i = 0; i < array.Length; i++)
        array[i] = new T();
    return array;
}

所以你可以这样做:

Sample[] array = new Sample[100].Populate();
于 2014-07-10T08:36:34.173 回答