C#中foreach实现原理详解
本文主要记录我在学习C#中foreach遍历原理的心得体会。
对集合中的要素进行遍历是所有编码中经常涉及到的操作,因此大部分编程语言都把此过程写进了语法中,比如C#中的foreach。经常会看到下面的遍历代码:
varlstStr=newList{"a","b"}; foreach(varstrinlstStr) { Console.WriteLine(str); }
实际此代码的执行过程:
varlstStr=newList{"a","b"}; IEnumerator enumeratorLst=lstStr.GetEnumerator(); while(enumeratorLst.MoveNext()) { Console.WriteLine(enumeratorLst.Current); }
会发现有GetEnumerator()方法和IEnumerator
为了方便理解,以下为非泛型示例:
//摘要: //公开枚举器,该枚举器支持在非泛型集合上进行简单迭代。 publicinterfaceIEnumerable { //摘要: //返回一个循环访问集合的枚举器。 // //返回结果: //可用于循环访问集合的System.Collections.IEnumerator对象。 IEnumeratorGetEnumerator(); }
实现了此接口的类称为可枚举类型,是可以用foreach进行遍历的标志。
方法GetEnumerator()的返回值是枚举器,可以理解为游标。
//摘要: //支持对非泛型集合的简单迭代。 publicinterfaceIEnumerator { //摘要: //获取集合中的当前元素。 // //返回结果: //集合中的当前元素。 // //异常: //System.InvalidOperationException: //枚举数定位在该集合的第一个元素之前或最后一个元素之后。 objectCurrent{get;} //摘要: //将枚举数推进到集合的下一个元素。 // //返回结果: //如果枚举数成功地推进到下一个元素,则为true;如果枚举数越过集合的结尾,则为false。 // //异常: //System.InvalidOperationException: //在创建了枚举数后集合被修改了。 boolMoveNext(); // //摘要: //将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。 // //异常: //System.InvalidOperationException: //在创建了枚举数后集合被修改了。 voidReset(); }
以下是自定义一个迭代器的示例(https://msdn.microsoft.com/en-us/library/system.collections.ienumerator.aspx):
usingSystem; usingSystem.Collections; //Simplebusinessobject. publicclassPerson { publicPerson(stringfName,stringlName) { this.firstName=fName; this.lastName=lName; } publicstringfirstName; publicstringlastName; } //CollectionofPersonobjects.Thisclass //implementsIEnumerablesothatitcanbeused //withForEachsyntax. publicclassPeople:IEnumerable { privatePerson[]_people; publicPeople(Person[]pArray) { _people=newPerson[pArray.Length]; for(inti=0;i在有了yield这个关键字以后,我们可以通过这样的方式来创建枚举器:
usingSystem; usingSystem.Collections; //Simplebusinessobject. publicclassPerson { publicPerson(stringfName,stringlName) { this.firstName=fName; this.lastName=lName; } publicstringfirstName; publicstringlastName; } //CollectionofPersonobjects.Thisclass //implementsIEnumerablesothatitcanbeused //withForEachsyntax. publicclassPeople:IEnumerable { privatePerson[]_people; publicPeople(Person[]pArray) { _people=newPerson[pArray.Length]; for(inti=0;i以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。