15

当与数组一起使用时,编译器会将foreach循环编译为类似于for循环的内容。当与or一起使用时foreach,编译器会将循环编译foreach成类似于循环的东西。那么这是否意味着纯粹?或者它有什么复杂之处?whileforeachIEnumerableIEnumerable<T>foreachsyntactic sugar

CLR 知道foreach吗?foreachMSIL 代码中是否有专门设计的内容?

4

5 回答 5

28

它是纯粹的语法糖,没有它你可以获得相同的行为,是的。许多其他事情都是一样的......for等等while......错误地引用阿基米德:“给我ifgoto,我会移动代码......”

不,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 循环中的项目是不可变的(不可更改的)。正如 Daniel 亲切地指出的那样,这样做的原因是大多数集合将在 foreach 中使用枚举器,而枚举器的限制是在枚举列表时不允许您更新列表的内容。

IE

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