c# - 'foreach' 循环的幕后发生了什么?

标签 c# foreach clr

<分区>

Possible Duplicate:
How do foreach loops work in C#?

我一直在互联网上搜索,但我无法找到关于 C# 中的 foreach 循环幕后真正发生的事情的任何答案。

我知道这个问题与实际编码无关,但它困扰着我。我对 OO 编程特别是接口(interface)很陌生。我了解它们是契约(Contract),并且我了解 IEnumerableIEnumerator 的工作原理 - 我认为是这样。

我一直在 MSDN 上阅读这篇文章: IEnumerable Interface

我了解一切是如何设置的。虽然在 Main 循环中我有点不清楚 foreach 如何知道遍历 _people 中的所有值。它怎么知道的?它如何通过调用 return new PeopleEnum(_people); 来跟踪Current

编辑:我看不出这是一个完全相同的副本。是的,它有相似的理由和相同的问题,但我们正在寻找不同的答案我想要的答案在上一个问题中没有讨论。

A foreach loop like foreach(int i in obj) {...} kinda equates to

...“有点”不是我正在寻找的答案。

最佳答案

我鼓励您阅读 C# 规范的第 8.8.4 节,其中详细回答了您的问题。为了您的方便,在这里引用它:


形式的foreach语句

foreach (V v in x) embedded-statement

然后扩展为:

{
    E e = ((C)(x)).GetEnumerator();
    try 
    {
        V v;
        while (e.MoveNext()) 
        {
            v = (V)(T)e.Current;
            embedded-statement
        }
    }
    finally 
    {
         code to Dispose e if necessary
    }
}

类型E、C、V、T是语义分析器推导出的枚举数、集合、循环变量和集合元素类型;有关详细信息,请参阅规范。

就这样吧。 “foreach”只是编写调用 MoveNext 直到 MoveNext 返回 false 的“while”循环的一种更方便的方式。

一些微妙的事情:

  • 这不一定是生成的代码;所需要的只是我们生成产生相同结果的代码。例如,如果你“foreach”一个数组或一个字符串,我们只生成一个“for”循环(或循环,在多维数组的情况下)来索引数组或字符串的字符,而不是采用以分配枚举器为代价。

  • 如果枚举数是值类型,则处置代码可能会或可能不会选择在处置枚举数之前将其装箱。不要以这种或另一种方式依赖它。 (有关相关问题,请参阅 http://blogs.msdn.com/b/ericlippert/archive/2011/03/14/to-box-or-not-to-box-that-is-the-question.aspx。)

  • 同样,如果上面自动插入的强制转换被确定为身份转换,则强制转换可能会被省略,即使这样做通常会导致值类型被复制。

  • C# 的 future 版本可能会将循环变量v 的声明放在 while 循环体中;这将防止在 Stack Overflow 上每天报告一次的常见“修改后的闭包”错误。 [更新: This change has indeed been implemented in C# 5 .]

关于c# - 'foreach' 循环的幕后发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7350495/

相关文章:

Java:如果使用 for-each 循环遍历集合,则可以替代 iterator.hasNext()

java - Java和.Net在JIT上有什么区别

c# - .NET 4.0 与旧版本性能比较

c# - 线程在操作系统上下文中的作用是什么?

javascript - 如何将刻度转换为 momentjs 对象

c# - 更新文件中的 xml 的最佳方法是什么?

r - 有没有办法打破foreach循环?

javascript - JS/Jquery - 如果输入有任何数组名称,则返回关联值

c# - 运算符 ‘==’ 不能应用于类型 ‘char’ 和 ‘string’ 的操作数

c# - 将 C# API 编写为 C++ 代码的包装器?