Answer:
 

I understand the IEnumerator/IEnumerable methods and properties and also how they are interrelated. But I fail to understand from the foreach loop perspective. Say for example, if I say the following line of code, how does the compiler look at foreach loop and break it down to IEnumerable/IEnumerator for every occurance of foreach loop in your code. In other words, what happens under the hood? I tried to go through couple of articles on the web. But they were NOT looked from the foreach loop perspective or I might have failed to understand. Could somebody explain with the example or direct me to any articles that explains clearly. All help is greatly appreciated.

Answer: To keep it short the compiler doesn't do much. It just translates the foreach code into a while under the hood. Here's an example:

List<int> list = new List<int>;

........

foreach(int item in list)

{

//Do stuff

}

Becomes:

Enumerator<int> enum = ((IEnumerable<int>)list).GetEnumerator();

enum.Reset();

while(enum.MoveNext())

{

int item = enum.Current;

//Do stuff

}

or something very close to that. The acual code compiled most likely has a try / finally block around the while to dispose the enumerator

IEnumerable is the base interface for all non-generic collections that can be enumerated. For the generic version of this interface see System.Collections.Generic.IEnumerable<T>. IEnumerable contains a single method, GetEnumerator, which returns an IEnumerator. IEnumerator provides the ability to iterate through the collection by exposing a Current property and MoveNext and Reset methods.

It is a best practice to implement IEnumerable and IEnumerator on your collection classes to enable the foreach (For Each in Visual Basic) syntax, however implementing IEnumerable is not required. If your collection does not implement IEnumerable, you must still follow the iterator pattern to support this syntax by providing a GetEnumerator method that returns an interface, class or struct. When using Visual Basic, you must provide an IEnumerator implementation, which is returned by GetEnumerator. When developing with C# you must provide a class that contains a Current property, and MoveNext and Reset methods as described by IEnumerator, but the class does not have to implement IEnumerator.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections; namespace CSharpExam
{
public class TestInumerable
{
public static void Run()
{
Person[] peopleArray = new Person[]
{
new Person("Steven", "Xia"),
new Person("Jim", "Johnson"),
new Person("Sue", "Rabon"),
}; People peopleList = new People(peopleArray);
foreach (Person p in peopleList)
Console.WriteLine(p.firstName + " " + p.lastName); }
} public class Person
{
public Person(string fName, string lName)
{
this.firstName = fName;
this.lastName = lName;
} public string firstName;
public string lastName;
} public class People //: IEnumerable
{
private Person[] _people;
public People(Person[] pArray)
{
_people = new Person[pArray.Length]; for (int i = ; i < pArray.Length; i++)
{
_people[i] = pArray[i];
}
} #region IEnumerable 成员 public PeopleEnum GetEnumerator()
{
return new PeopleEnum(_people);
} #endregion
} public class PeopleEnum //: IEnumerator
{
public Person[] _people; // Enumerators are positioned before the first element
// until the first MoveNext() call.
int position = -; public PeopleEnum(Person[] list)
{
_people = list;
} public bool MoveNext()
{
position++;
return (position < _people.Length);
} public void Reset()
{
position = -;
} public object Current
{
get
{
try
{
return _people[position];
}
catch (IndexOutOfRangeException)
{
throw new InvalidOperationException();
}
}
}
} }

随机推荐

  1. ChemDraw怎么绘制H-点或H-划

    ChemDraw软件是一款全球领先的化学绘图工具,能够绘制各类化学结构图形和化学方程式,在基础化学.有机化学和分析化学等领域得到了广泛的应用.H-点和H-划是日常作图过程中使用频率较高的化学符号,必须 ...

  2. 数据库已有时间索引,想再添加ID索引

    将时间索引的代码复制进去后,将编辑框的变量改为m_QueryID. 准备先以时间索引查找出大概数据,再直接使用ID索引精确查找. 于是想直接精确查ID为105的数据信息. 出现错误: 发现错误原因是忘 ...

  3. windows性能监视器的使用

    https://blog.csdn.net/ab7434588/article/details/53023799 一般在客户端通过LoadRunner对服务器进行压力测试,都需要实时监控服务器端的系统 ...

  4. iOS开发之--调用打电话,发邮件,发短信的系统功能的代码

    1.调用 自带mail [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"mailto://admin@hz ...

  5. C语言二维数组

    上节讲解的数组可以看作是一行连续的数据,只有一个下标,称为一维数组.在实际问题中有很多数据是二维的或多维的,因此C语言允许构造多维数组.多维数组元素有多个下标,以确定它在数组中的位置.本节只介绍二维数 ...

  6. 部分常用dos命令

    Microsoft Windows XP [版本 ] (C) 版权所有 - Microsoft Corp. C:\Documents and Settings\Administrator>d: ...

  7. Cocos2d-x学习之 整体框架描述

    1.Cocos2d-x 整体描述 和传统的游戏引擎一样,cocos2d-x作为一个2d的游戏引擎,其也有以下几大概念组成: 导演(CCDiretor): 在cocos2d-x引擎中,CCDirecto ...

  8. 170413、怎么精确理解leader布置的任务(技术外的话)

    [缘起] 和一个同学交代了一个很重要的事情,结果执行的结果并不是自己想要的,微微生气之余,简单的聊聊“如何精确的理解leader布置的任务”. [员工角度的潜在困惑] 1)leader讲了很多,脑子记 ...

  9. 160516、redis安装(linux+windows)

    1.windows中redis安装使用 第一步:下载windows版本的redis这里redis_win.zip并解压,加压后目录中有下面的文件 redis-server.exe   redis服务端 ...

  10. 修改Linux的基本配置(如主机名、ip等)

    1.修改主机名 vi /etc/sysconfig/network 2.修改ip地址(注意修改完了后,reboot) 查看网卡的命令: ifconfig 开启网卡的命令: ifup eth0 修改ip ...