介绍
小编给大家分享一下c#中foreach实现原理是什么,希望大家阅读完这篇文章后大所收获、下面让我们一起去探讨吧!
对集合中的要素进行遍历是所有编码中经常涉及到的操作,因此大部分编程语言都把此过程写进了语法中,比如c#中的foreach。经常会看到下面的遍历代码:
var lstStr=new List{“a",“b"}; foreach (var str lstStr) { Console.WriteLine (str); }
实际此代码的执行过程:
var lstStr=new List{“a",“b"}; IEnumerator enumeratorLst=lstStr.GetEnumerator (); 而(enumeratorLst.MoveNext ()) { Console.WriteLine (enumeratorLst.Current); }
会发现有GetEnumerator()方法和IEnumerator
为了方便理解,以下为非泛型示例:
//摘要://公开枚举器,该枚举器支持在非泛型集合上进行简单迭代。 公共接口IEnumerable {//摘要://返回一个循环访问集合的枚举器。////返回结果://可用于循环访问集合的System.Collections。IEnumerator对象。 IEnumerator GetEnumerator (); }
实现了此接口的类称为可枚举类型,是可以用foreach进行遍历的标志。
方法GetEnumerator()的返回值是枚举器,可以理解为游标。
//摘要://支持对非泛型集合的简单迭代。 公共接口IEnumerator {//摘要://获取集合中的当前元素。////返回结果://集合中的当前元素。////异常://System.InvalidOperationException://枚举数定位在该集合的第一个元素之前或最后一个元素之后。 对象当前{得到;}//摘要://将枚举数推进到集合的下一个元素。////返回结果://如果枚举数成功地推进到下一个元素,则为正确的;如果枚举数越过集合的结尾,则为错误的。////异常://System.InvalidOperationException://在创建了枚举数后集合被修改了。 bool MoveNext ();////摘要://将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。////异常://System.InvalidOperationException://在创建了枚举数后集合被修改了。 空白重置(); }
以下是自定义一个迭代器的示例(https://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx):
使用系统; 使用System.Collections;//简单的业务对象。 公开课的人 { 公众人物(帧的字符串,字符串lName) { 这一点。firstName=帧; 这一点。lastName=lName; } 公共字符串firstName; 公共字符串姓; }//Person对象的集合。这个类//实现IEnumerable,以便它可以被使用//用ForEach语法。 公共类:IEnumerable { 个人[]_people; 公共人(人[]pArray) { _people=新人(pArray.Length); for (int i=0;我& lt;pArray.Length;我+ +) { _people[我]=pArray[我]; } }//实现GetEnumerator方法。 IEnumerator IEnumerable.GetEnumerator () { 返回(IEnumerator) GetEnumerator (); } 公共PeopleEnum GetEnumerator () { 返回新PeopleEnum (_people); } }//当你实现IEnumerable,您还必须实现IEnumerator。 公开课PeopleEnum: IEnumerator { 公众人物[]_people;//枚举器定位第一个元素之前//直到第一次MoveNext()调用。 int位置=1; 公共PeopleEnum(人[]列表) { _people=列表; } 公共bool MoveNext () { 位置+ +; 返回(位置& lt;_people.Length); } 公共空间重置() { 位置=1; } 对象IEnumerator.Current { 得到 { 返回当前; } } 当前公众人物 { 得到 { 试一试 { 返回_people(位置); } 抓住(IndexOutOfRangeException) { 把新InvalidOperationException (); } } } } 类应用 { 静态void Main () { 人[]peopleArray=new [3] { 新人(“John",“Smith"), 新人(“Jim",“Johnson"), 新人(“Sue",“Rabon"), }; 人们peopleList=new (peopleArray); foreach(人在peopleList页) Console.WriteLine (p。firstName +“;“;+ p.lastName); } }/*此代码生成的输出如下: * *约翰史密斯 *吉姆。约翰逊 *苏Rabon * */
在有了产生这个关键字以后,我们可以通过这样的方式来创建枚举器: