2011-01-29 117 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();