使用默认构造函数初始化数组
public class Sample { static int count = 0; public int abc; public Sample() { abc = ++Sample.count; } }
我想创建一个上面的类数组,并希望通过调用默认构造函数来初始化数组中的每个元素,这样每个元素都可以有不同的abc
。所以我这样做了:
Sample[] samples = new Sample[100];
但这并不符合我的想法。 这似乎是默认构造函数没有被调用。 如何在创建数组时调用默认构造函数?
我也想知道上面的陈述是做什么的?
基本上你不能。 创建数组时,它始终最初使用类型的默认值填充 – 对于类,该类始终为空引用。 对于int
它是0,对于bool
它是假的,等等。
(如果使用数组初始值设定项,则会创建“空”数组, 然后使用您指定的值填充它。)
通过调用构造函数可以通过各种方式填充数组 – 我可能只是自己使用foreach循环。 使用LINQ和Enumerable.Range / Repeat感觉有点强迫。
当然,您总是可以编写自己的填充方法,即使是作为扩展方法:
public static T[] Populate(this T[] array, Func provider) { for (int i = 0; i < array.Length; i++) { array[i] = provider(); } return array; }
然后你可以使用:
Sample[] samples = new Sample[100].Populate(() => new Sample());
我喜欢这个解决方案:
- 它仍然是单个表达式,在各种情况下都很有用
- 它没有介绍您实际不需要的概念(例如重复单个值或创建范围)
当然你可以添加更多选项:
- 一个重载,它接受
Func
而不是Func
,将索引传递给提供者 - 一种非扩展方法,用于创建数组并填充它
您的代码只创建数组 ,但不创建任何项目。 基本上,您需要将Sample
实例存储到此数组中。
简单来说,没有任何花哨的LINQ等:
Sample[] samples = new Sample[100]; for (int i = 0; i < samples.Length; i++) samples[i] = new Sample();
另请注意,您的解决方案不是线程安全的。
没有办法自动执行此操作; 数组初始化本质上是“将这块内存擦除为0”。 你必须做类似的事情:
var arr = new SomeType[size]; for(int i = 0 ; i < size ; i++) arr[i] = new SomeType();
此时你有一个大小为100的空数组,如果你想用它填充它,那么你必须做类似的事情:
for(int i=0; i
问题是通过声明该数组,您从未为每个对象分配空间。 您只为100个Sample类型的对象分配了空间。 你必须自己调用构造函数。
详细说明:
Food[] foods = Food[100]; for (int k = 0; k < foods.length; k++) { foods[k] = new Food(); }
一个有趣的工作可能是工厂function。 考虑将其附加到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; }
隐藏瑕疵,有点 - 这对你来说是一个有用的function。
这是另一个不需要任何扩展方法的单行程序:
Sample[] array = Enumerable.Range(0, 100).Select(i => new Sample()).ToArray();
另一个不错的选择是Scott对Jon的回答 的建议 :
public static T[] Populate(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();