c#中foreach实现原理是什么

  介绍

小编给大家分享一下c#中foreach实现原理是什么,希望大家阅读完这篇文章后大所收获、下面让我们一起去探讨吧!

对集合中的要素进行遍历是所有编码中经常涉及到的操作,因此大部分编程语言都把此过程写进了语法中,比如c#中的foreach。经常会看到下面的遍历代码:

 var lstStr=new List{“a",“b"};
  foreach (var str lstStr)
  {
  Console.WriteLine (str);
  }

实际此代码的执行过程:

 var lstStr=new List{“a",“b"};
  IEnumeratorenumeratorLst=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
  *
  */

在有了产生这个关键字以后,我们可以通过这样的方式来创建枚举器:

c#中foreach实现原理是什么