2011-01-29 116 views
15
public class Sample 
{ 
    static int count = 0; 
    public int abc; 
    public Sample() 
    { 
     abc = ++Sample.count; 
    } 
} 

我想创建上述类的数组,并希望阵列中的每个元件通过调用默认构造进行初始化,使每个元件可以有不同的abc。所以我这样做:数组初始化与默认的构造

Sample[] samples = new Sample[100]; 

但是这并没有做我认为应该做的事情。看来这种方式默认的构造函数没有被调用。如何在创建数组时调用默认构造函数?

我也想知道上面的说法是干什么的?

+0

你为什么不只是使用数组的索引,它的独特和经销商的增量,按您的代码 – 2011-01-29 21:18:46

+2

在一个侧面说明 - 该代码是不是线程安全的;你应该使用'id = Interlocked.Increment(ref count)`而不是`static int count = 1`(因为`Interlocked.Increment`返回* old *的值)。 – 2011-01-29 21:20:18

+0

在上面的代码中,你刚刚声明了一个大小为100的数组,其中没有任何项目。 – Victor 2011-01-29 21:20:57

回答

38

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

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

通过调用构造函数来填充数组有多种方法 - 我会可能只是自己使用foreach循环。使用LINQ与Enumerable.Range/Repeat有点被迫。

当然,你总是可以自己群体的方法,甚至作为一个扩展的方法:

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()); 

我喜欢这个怎么样的解决方案:

  • 它仍然是一个单一的表达式,它可以用于各种场景
  • 它不介绍你其实不愿意概念(如重复单个值或创建范围)

当然,你可以添加更多的选择:

  • 一个重载需要Func<int, T>代替Func<T>,传递索引到提供商
  • 并且会创建阵列填充它的非扩展方法
4

有没有办法自动做到这一点;数组初始化本质上是“将这块内存擦除为0”。你将不得不做这样的事情:

var arr = new SomeType[size]; 
for(int i = 0 ; i < size ; i++) arr[i] = new SomeType(); 
8

你的代码创建只有阵列,但既不是它的项目。基本上,您需要将店铺实例Sample分成这个数组。

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

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

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

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

隐藏瑕疵,有点 - 提供这是一个有用的功能给你。

2

在这一点上你有大小100的空数组,如果你想用项目来填补它,那么你就必须这样做:

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

这里是另外一个班轮那并不是”牛逼需要任何扩展方法:

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

另一个不错的选择是Scott's suggestionJon's answer

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();