Is foreach purely “syntactic sugar”?
The compiler compiles a foreach
loop into something like a for
loop when the foreach
is used with an array. And the compiler compiles a foreach
loop into something like a while
loop when the foreach
is used with an IEnumerable
or IEnumerable<T>
. So does this mean foreach
is pure开发者_Python百科ly syntactic sugar
? Or is there anything sophisticated about it?
Does the CLR know about foreach
? Is there anything specifically designed for foreach
in the MSIL code?
It's purely syntactic sugar in that you could obtain the same behaviour without it, yes. Many other things are the same... for
, while
etc... To misquote Archimedes: "Give me if
and goto
, and I will move the code..."
No, the CLR doesn't have any concept of foreach
.
It is syntactic sugar. However, note that foreach works by calling GetEnumerator(), then MoveNext() until there is no further item returned and then always calls Dispose() on the enumerator it previously obtained. If you want to do it the same way, don't forget that Dispose()!
Also, the CLR does some tricks related to getting the enumerator. See here and here, for example.
foreach
is internally just a while
loop that calls the methods in IEnumerator
.
Yes, it is purely sugar. The following code
var MyList = new List<int>() { 10 , 20 , 30 , 40, 50} ;
foreach(int i in MyList)
{
Console.WriteLine(i);
}
is translated in compiler as:
Ienumrator<int> rator = MyList.GetEnumrator();
try
{
while(rator.MoveNext())
{
int i = rator.Current;
Console.WriteLine(i);
}
}
finally
{
rator.Dispose()
}
It is not just syntactic sugar as the items in a foreach loop are immutable (unchangeable). The reason for this, as Daniel so kindly pointed out, is that most collections will use an enumerator in a foreach, and it is the enumerator that has the restriction of not letting you update the contents of the list while it is being enumerated.
i.e.
Foreach(String s in List<string>)
{
s = "f"; //this will throw an error.
}
精彩评论