classPRogram
{
staticvoidMain(string[]args)
{
Console.WriteLine("***第一種情況************************************************");
string[]array11=newstring[]{"111","222","333"};
string[]array12=newstring[]{"111","222","333"};
for(inti=0;i<array11.Length;i++)
{
Console.WriteLine(array11[i]);
}
Console.WriteLine("=========================");
foreach(stringsinarray12)
{
Console.WriteLine(s);
}
/*結果
111
222
333
=========================
111
222
333
*/
//都是根據length來對數據進行循環
//不同的是foreach里自動對array進行index+1的操作來循環,而for則是自己的代碼控制的
Console.WriteLine("***第二種情況************************************************");
string[]array21=newstring[]{"111","222","333"};
string[]array22=newstring[]{"111","222","333"};
for(inti=0;i<array21.Length;i++)
{
Console.WriteLine(array21[i]);
array21=newstring[]{"AAA","BBB","CCC"};
}
Console.WriteLine("=========================");
foreach(stringsinarray22)
{
Console.WriteLine(s);
array22=newstring[]{"AAA","BBB","CCC"};
}
/*結果
111
BBB
CCC
=========================
111
222
333
*/
//不一樣了吧,看來在foreach內部的循環中對源數據的更改不是即時生效的
//在foreach(...)循環里盡量不要更改操作的源數據
Console.ReadKey();
}
}
namespacefor_foreach2
{
classProgram
{
staticvoidMain(string[]args)
{
//使用測試類E,做for和foreach的循環
string[]array31=newstring[]{"111","222","333"};
Ee=newE(array31);
foreach(stringsine)
{
Console.WriteLine(s);
}
/*result
333
222
111
Disposehere!
*/
//差異出現了,這次是按照倒序的方式,而且還自動調用了Dispose方法!
Console.ReadKey();
}
}
//根據MS的參考,能在foreach上做循環的只能是實現了IEnumerable接口。
//(事實上,System.Array也是實現了IEnumerable接口的)
//這兒做一個在IEnumerable上的循環
publicclassE:System.Collections.IEnumerable
{
privateInnerEnumeratorinner;
publicE(string[]array)
{
this.inner=newInnerEnumerator(array);
}
#regionIEnumerableMembers
publicIEnumeratorGetEnumerator()
{
returnthis.inner;
}
#endregion
privateclassInnerEnumerator:IEnumerator,IDisposable
{
privatestring[]s;
privateintcurrentIndex;
publicInnerEnumerator(string[]array)
{
this.s=array;
this.Reset();
}
#regionIEnumeratorMembers
//Resetindextooriginal(重置索引為原始的)
publicvoidReset()
{
this.currentIndex=s.Length-1;
}
//GetCurrentobjectinner
publicobjectCurrent
{
get
{
objecto=this.s[this.currentIndex];
this.currentIndex--;
returno;
}
}
//Istherehasanyotherobjectinthearray?
publicboolMoveNext()
{
if(this.currentIndex<0)
{
returnfalse;
}
returntrue;
}
#endregion
#regionIDisposableMembers
//DisposeHere()
publicvoidDispose()
{
Console.WriteLine("Disposehere!");
}
#endregion
}
}
}
綜合上面,得出如下結論:1.for循環并不依賴于數組或其他形式的組式數據結構,只是簡單的 在調用了代碼后,進行一個判斷,判斷是否要繼續。 (非常類似于do..while和while循環--在這里不作具體分析了^_^~~)2.foreach循環如果作用在一個基于System.Array的類型之上的數組的話,編譯器會自動優化成與for循環非常類似 的代碼,只是調用的指命有細微的差別,并且檢查(包括編譯階段和運行時)會比for嚴格的多3.foreach循環作用在一個非System.Array類型上(且一定要是實現了IEnumerable接口的類),會先調用 IEnumerable.GetEnumerator()方法獲取一個Enumertor實例,再在獲取的Enumertor實例上調用 GetCurrent()和MoveNext()方法,最后判斷如果Enumertor實例如果實現了IDispose接口,就自動調用 IDispose.Dispose()方法!
那么我們應該分別在那些地方用for和foreach捏建議:1.在有對所循環的本體(System.Array)做賦值操作時,盡量不要用Foreach()。2.foreach比for更靈活。(可在MoveNext()和GetCurrent()里編寫自己的代碼). 自己編寫的類如果實現了IEnumerable接口的話,就可以用foreach循環了,而不管內部是否有一個真實的數組, 并且可以自定義循環的規則。3.從OO的原則看,foreach循環更適于多數情況的使用 (事實上,foreach的實現是典型的Iterator模式,下面有簡單的描述它的好處) 想用統一的調用循環接口時,foreach是最佳的選擇 (MS有很多類就是這樣的,例如前面提到的DataRowCollection.)
參考至:C#里for和foreach的區別 - lyh830612的日志 - 網易博客
新聞熱點
疑難解答