你的位置:首页 > ASP.net教程

[ASP.net教程]C#之foreach实现探秘


代码 1:
static void Main(string[] args) { int[] hs = { 1,2,3,4,5,6,7,8,9}; foreach (int item in hs) { Console.WriteLine(item.ToString()); } Console.ReadKey(); }

代码 2:
static void Main(string[] args) { ArrayList ArrLst = new ArrayList(); ArrLst.AddRange(new string[] { "jack","rose","joy","kristina"}); foreach (string s in ArrLst) { Console.WriteLine(s); } Console.ReadKey(); }

   为什么代码 1 和 代码 2可以使用foreach来循环遍历int数组的元素?

代码 3:
using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;namespace ForeachDemo{ class Dog { //构造函数 public Dog(params string[] dogNames) { DogNames.AddRange(dogNames); } //名称字段、属性 private string name; public string Name { get { return name; } set { name = value; } } //List<string>集合元素数 public int DogNamesCounts() { return DogNames.Count; } public List<string> DogNames = new List<string>(); //Dog类对象所引器 public string this[int index] { get { return DogNames[index];} set { if (index >= DogNames.Count) { DogNames.Add(value); } else { DogNames[index] = value; } } } } class Program { static void Main(string[] args) { Dog D = new Dog("哈士奇","吉娃娃","藏獒","牧羊犬"); //for循环可以通过所引器访问对象 //for (int i = 0; i < D.DogNames.Count; i++) //{ // Console.WriteLine(D[i].ToString()); //} //foreach却不能通过所引器遍历 foreach (string s in D) { Console.WriteLine(s); } Console.ReadKey(); } }}

   为什么代码 3 不可以通过foreach循环遍历呢?

  原因分析:

  • 数组(Array)实现了IEnumerable接口(公开枚举器,该枚举器支持在非泛型集合上进行简单迭代。)
  • 要想自己编写的类也具有foreach循环遍历的能力,这个类得实现IEnumerator接口(非泛型)

  那针对以上代码的修改如下:

using System;using System.Collections;using System.Collections.Generic;using System.Linq;using System.Text;namespace ForeachDemo{  class Dog:IEnumerable  {    //构造函数    public Dog(params string[] dogNames)    {      DogNames.AddRange(dogNames);    }    //名称字段、属性    private string name;    public string Name    {      get { return name; }      set { name = value; }    }    //List<string>集合元素数    public int DogNamesCounts()    {      return DogNames.Count;    }    public List<string> DogNames = new List<string>();    //Dog类对象所引器    public string this[int index]    {      get { return DogNames[index]; }      set      {        if (index >= DogNames.Count)        {          DogNames.Add(value);        }        else        {          DogNames[index] = value;        }      }    }    //这里需要一个IEnumerator类型的对象返回值(显式实现IEnumerable)    //IEnumerator IEnumerable.GetEnumerator()    //{    //  throw new NotImplementedException();    //}    public IEnumerator GetEnumerator()    {      return new DogEnumerator(this.DogNames);    }  }  public class DogEnumerator:IEnumerator  {    /* 显式实现IEnumerator接口    object IEnumerator.Current    {      get { throw new NotImplementedException(); }    }    bool IEnumerator.MoveNext()    {      throw new NotImplementedException();    }    void IEnumerator.Reset()    {      throw new NotImplementedException();    }*/    //构造函数    public DogEnumerator(List<string> paramDogNames)    {      this.dogsNames = paramDogNames;    }    List<string> dogsNames = new List<string>();    //枚举器初始索引    private int index = -1;    //获取集合中的当前元素    public object Current    {      get      {        if (index < 0)        {          return null;        }        else        {          return dogsNames[index];        }      }    }    //判断是否可以将枚举数推进到集合的下一个元素    public bool MoveNext()    {      index += 1;      if (index >= dogsNames.Count)      {        return false;      }      else      {        return true;      }    }    //将枚举数设置为其初始位置,该位置位于集合中第一个元素之前(索引为-1)    public void Reset()    {      this.index = -1;    }  }  class Program  {    static void Main(string[] args)    {      Dog D = new Dog("哈士奇", "吉娃娃", "藏獒", "牧羊犬");      //for循环可以通过所引器访问对象      //for (int i = 0; i < D.DogNames.Count; i++)      //{      //  Console.WriteLine(D[i].ToString());      //}      foreach (string s in D)      {        Console.WriteLine(s);      }            Console.ReadKey();    }  }}