2012-09-19 25 views
0

考慮下面的代碼:foreach所的System.Array

static void Main() { 
    string[] myArray = {"One", "Two", "Three"}; 

    PrintArray(myArray); 
} 

static void PrintArray(System.Array array1) { 

    foreach (string s in array1) 
     Console.WriteLine(s); 
} 

我很驚訝,我可以無錯地編譯那些行,因爲在PrintArray編譯器無法知道什麼樣的陣列陣列1的是(在這種情況下,它是System.string[])。如果我更改foreach這樣的行:foreach (int s in array1),代碼仍會編譯,但會生成運行時無效的轉換異常。

在這種情況下編譯不應該保證只有對象可以在foreach語句中使用嗎?

回答

2

通過指定循環變量的類型,您顯式拆箱/將陣列中的每個元素都轉換爲該類型。

在字符串的情況下,它是從對象到字符串的強制轉換。
如果你的數組是一個int數組,你將會進行拆箱操作而不是轉換。

+0

兩個nitpicks:'foreach'顯式轉換每個元素,就像一個轉換,但是轉換指的是'(T)o'語法,這裏不存在,所以沒有轉換。拆箱是潛在的顯式轉換之一,因此它不是拆箱或顯式轉換,而是始終顯式轉換,有時可能會拆箱,有時會進行另一次轉換。 – hvd

+0

@hvd:我沒有意識到術語中的這些細微差別,特別是在「顯式轉換」和「投射」之間。你有這些的任何參考?順便說一句:「特定演員陣容無效」的例外暗示了正在發生的演員陣容。 –

+0

這就是它在C#語言規範中的用法,例如在7.7.6 Cast表達式上查找。儘管有關異常消息的好處。 – hvd

0

編譯器知道你正在傳遞一個System.Array,這是一個基於object的集合。它不能靜態地知道數組包含的是什麼類型的對象,所以沒有辦法確保代碼在一般情況下無錯地運行。轉換到int必須在運行時執行並可能失敗。