2008-11-12 33 views
3

當C#代碼看,我經常看到這樣的模式中:在items在對象使用的foreach(...)語法,同時還增加一個索引變量循環

DataType[] items = GetSomeItems(); 
OtherDataType[] itemProps = new OtherDataType[items.Length]; 

int i = 0; 
foreach (DataType item in items) 
{ 
    // Do some stuff with item, then finally 
    itemProps[i] = item.Prop; 
    i++; 
} 

for循環迭代,而且還保留一個計數器(i)以便迭代itemProps。我個人不喜歡這種額外的i遊逛,而是可能會做這樣的事情:

DataType[] items = GetSomeItems(); 
OtherDataType[] itemProps = new OtherDataType[items.Length]; 

for (int i = 0; i < items.Length; i++) 
{ 
    // Do some stuff with items[i], then finally 
    itemProps[i] = items[i].Prop; 
} 

有可能還有一些benfit第一種方法,我不知道的?這是每個人都試圖使用那種奇特的foreach (...)語法的結果嗎?我對你對此的看法感興趣。

回答

2

在這種情況下,我不這麼認爲。雖然有時候,集合並不實現this[int index],但它確實實現了GetEnumerator()。在後一種情況下,你沒有太多選擇。

4

當我在數組之外時,如果在循環完成後可用。如果您想計算項目的數量,並且該集合沒有提供.Count或.UBound屬性,那麼這可能很有用。

就像你我通常會使用第二種方法,看起來更清潔。

7

如果您使用的是C#3.0,那會更好;

OtherDataType[] itemProps = items.Select(i=>i.Prop).ToArray(); 
+0

尼斯 - 清潔仍然。 – DilbertDave 2008-11-12 13:56:43

1

一些數據結構不適合隨機訪問,但可以非常快速地進行迭代(樹,鏈表等)。所以,如果你需要遍歷其中的一個,但需要計數出於某種原因,你註定要走醜的方式...

1

語義上它們可能是等價的,但實際上使用foreach在枚舉器上給編譯器更多範圍進行優化。

我不記得我頭頂上的所有論點,但他們很好地涵蓋在有效的C#,這是推薦閱讀。

1

foreach(項目中的DataType項目) 這個foreach循環很清楚你正在迭代所有的DataType項目,當然是項目。也許它使代碼更長一些,但它不是一個「壞」的代碼。對於另一個for循環,您需要檢查括號內的內容以瞭解此循環的用途。

這個例子的問題在於,你在同一時間迭代了兩個不同的數組,我們不經常這樣做......所以我們被困在兩個策略之間..要麼我們「當你打電話給它時,或者我們回到舊的不太被愛的地方(int i = 0; i ...)。 (當然,除了這兩個以外,還有其他方法)

所以,我認爲這是Vim vs Emacs的事情,在For vs Foreach循環中回到你的問題:)喜歡for()的人會說這個foreach是無用的,可能會導致性能問題,並且只是很大。預先聲明的人會說這樣的話,如果我們可以讀取代碼並輕鬆維護它,我們不在乎是否有兩個額外的行。

最後,我在範圍之外的第一個例子和內部的第二個..原因呢?!因爲如果你在你的foreach之外使用我,我會有不同的調用方式。而且,就我的意見而言,我更喜歡以前的方式,因爲您立即看到發生了什麼。您也不必考慮是否<或=。你馬上知道你正在遍歷所有的列表,但是,不幸的是,人們最後會忘記i ++:所以,我說Vim!

1

不要忘記,一些集合不實現直接訪問操作符[],並且您必須使用foreach()最容易訪問的IEnumerable接口進行迭代。

相關問題