2010-08-05 33 views
30

我無法弄清楚如何使這項工作:如何使用Reflection創建C#數組並僅使用類型信息?

object x = new Int32[7]; 
Type t = x.GetType(); 

// now forget about x, and just use t from here. 

// attempt1 
object y1 = Activator.CreateInstance(t); // fails with exception 

// attempt2 
object y2 = Array.CreateInstance(t, 7); // creates an array of type Int32[][] ! wrong 

有什麼祕訣?如果我能得到數組元素的類型,我可以使第二個工作,但我還沒有想出這一個。

+3

你讓我在「祕密醬」。 =) – 2010-08-05 22:00:58

回答

30

只是添加到喬恩的答案。嘗試1失敗的原因是因爲Int32[]沒有默認構造函數。你需要提供一個長度。如果你使用重載,這需要一系列的參數它將工作:

// attempt1 
object y1 = Activator.CreateInstance(t, new object[] { 1 }); // Length 1 
+3

這兩個答案都讓我走出泡菜,但我認爲這是更優雅的方法。我不會猜到這個答案,但是我看到如何有必要爲數組的構造函數提供參數,因爲數組的長度不是該類型的一部分。 – 2010-08-07 04:20:22

+0

剛剛使用過這個和來自http://stackoverflow.com/a/20052747/561690的塊來啓用處理陣列的Deep Copy實現 - 可能不是實現它的最佳方式,但它對我很有用!謝謝! – 2014-07-31 15:51:57

+0

簡單:Activator.CreateInstance(t,1) – 2015-07-07 10:17:34

41

你需要Type.GetElementType()獲得非數組類型:

object x = new Int32[7]; 
Type t = x.GetType(); 
object y = Array.CreateInstance(t.GetElementType(), 7); 

另外,如果你可以直接得到該元素的類型,使用的是:

Type t = typeof(int); 
object y = Array.CreateInstance(t, 7); 

基本上,Array.CreateInstance需要要創建的數組的元素類型,而不是最終的數組類型。

+0

這並不能回答爲什麼它不能與// attempt1一起工作,但我對自己很好奇(假設// attempt2有效)。 – zebediah49 2010-08-05 21:51:08

+0

我發佈我的問題幾秒鐘後,我發現了GetElementType(),這就是我實現它的方式。 我的目標是製作一個TreeView派生的小部件,它可以讓你拋出任何結構體(包括數組,主體和更多結構體的任意字段),並顯示整個事物並讓你編輯它並給你一個編輯的結構。 – 2010-08-07 04:23:08

相關問題