15

コンパイラは、が配列で使用される場合、ループforeachをループのようなものにコンパイルします。また、コンパイラは、がまたはで使用される場合、ループをループのようなものにコンパイルします。それで、これは純粋に意味するのでしょうか?それともそれについて洗練されたものはありますか?forforeachforeachwhileforeachIEnumerableIEnumerable<T>foreachsyntactic sugar

CLRは知っていforeachますか?foreachMSILコードで特別に設計されたものはありますか?

4

5 に答える 5

28

はい、それなしで同じ振る舞いを得ることができるという点で、それは純粋に構文糖衣です。他の多くのことは同じです...forなどwhile...アルキメデスを誤って引用するには:「私ifとを与えてくださいgoto、そして私はコードを移動します...」

いいえ、CLRにはの概念はありませんforeach

于 2011-04-28T09:56:53.503 に答える
10

糖衣構文です。ただし、foreachはGetEnumerator()を呼び出し、次にアイテムが返されなくなるまでMoveNext()を呼び出してから、以前に取得した列挙子に対して常にDispose()を呼び出すことで機能することに注意してください。同じようにしたい場合は、Dispose()を忘れないでください!

また、CLRは、列挙子の取得に関連するいくつかのトリックを実行します。たとえば、ここここを参照してください。

于 2011-04-28T10:07:21.427 に答える
2

foreach内部的には、のメソッドを呼び出す単なるwhileループですIEnumerator

于 2011-04-28T10:05:51.343 に答える
1

はい、それは純粋な砂糖です。次のコード

var MyList = new List<int>() { 10 , 20 , 30 , 40, 50} ;  
foreach(int i in MyList) 
{
    Console.WriteLine(i);
}

コンパイラでは次のように翻訳されます。

Ienumrator<int> rator = MyList.GetEnumrator();

try
{
   while(rator.MoveNext())
   {
       int i = rator.Current; 
       Console.WriteLine(i); 
   }
}
finally
{
    rator.Dispose()
}
于 2019-04-28T13:46:54.483 に答える
0

foreachループ内の項目は不変(変更不可)であるため、これは単なる構文糖衣ではありません。ダニエルがとても親切に指摘したように、この理由は、ほとんどのコレクションがforeachで列挙子を使用するためであり、列挙されている間はリストの内容を更新できないという制限があるのは列挙子です。

すなわち

Foreach(String s in List<string>)
{
   s = "f";  //this will throw an error.
}
于 2011-04-28T13:41:18.490 に答える