(譯注:這樣看上去雖然代碼很多,但我覺得 ,只要是程序員都可以一眼看出這是個三維數組的循環,但是對於foreach,我 看沒人一眼可以看出來它在做什麼! 個人理解。當然,這要看你怎樣認識,這當 然可以說是foreach的一個優點。)
事實上,foreach循環還可以在每個維 的下限不同的多維數組上工作(譯注:也就是鋸齒數組)。 我不想寫這樣的代碼 ,即使是為了做例示。但當某人在某時寫了這樣的集合時,foreach可以勝任。
foreach也給了你很大的伸縮性,當某時你發現須要修改數組裡底層的數 據結構時,它可以盡可能多的保證代碼不做修改。我們從一個簡單的數組來討論 這個問題:
int [] foo = new int[100];
假設後 來某些時候,你發現它不具備數組類(array class)的一些功能,而你又正好要 這些功能。你可能簡單把一個數組修改為ArrayList:
// Set the initial size:
ArrayList foo = new ArrayList( 100 );
任何用for循環的代碼被破壞:
int sum = 0;
for ( int index = 0;
// won't compile: ArrayList uses Count, not Length
index < foo.Length;
index++ )
// won't compile: foo[ index ] is object, not int.
sum += foo[ index ];
然而,foreach循環可以根據所操作的對象不同,而自 動編譯成不同的代碼來轉化恰當的類型。什麼也不用改。還不只是對標准的數組 可以這樣,對於其它任何的集合類型也同樣可以用foreach.
如果你的集 合支持.Net環境下的規則,你的用戶就可以用foreach來迭代你的數據類型。為 了讓foreach語句認為它是一個集合類型,一個類應該有多數屬性中的一個:公 開方法GetEnumerator()的實現可以構成一個集合類。明確的實現IEnumerable接 口可以產生一個集合類。實現IEnumerator接口也可以實現一個集合類。foreach 可以在任何一個上工作。
foreach有一個好處就是關於資源管理。 IEnumerable接口包含一個方法:GetEnumerator()。foreach語句是一個在可枚 舉的類型上生成下面的代碼,優化過的:
IEnumerator it = foo.GetEnumerator( ) as IEnumerator;
using ( IDisposable disp = it as IDisposable )
{
while ( it.MoveNext( ))
{
int elem = ( int ) it.Current;
sum += elem;
}
}
如果斷定枚舉器實現了IDisposable接口,編譯器可以自動優 化代碼為finally塊。但對你而言,明白這一點很重要,無論如何,foreach生成 了正確的代碼。
foreach是一個應用廣泛的語句。它為數組的上下限自成 正確的代碼,迭代多維數組,強制轉化為恰當的類型(使用最有效的結構),還有 ,這是最重要的,生成最有效的循環結構。這是迭代集合最有效的方法。這樣,你寫出的代碼更持久(譯注:就是不會因為錯誤而改動太多的代碼),第一次寫代 碼的時候更簡潔。這對生產力是一個小的進步,隨著時間的推移會累加起來。
返回教程目錄