如何才能在 foreach 语句中使用 C# 类

重要说明:本文是由 Microsoft 机器翻译软件进行的翻译并可能由 Microsoft 社区通过社区翻译机构(CTF)技术进行后期编辑,或可能是由人工进行的翻译。Microsoft 同时向您提供机器翻译、人工翻译及社区后期编辑的文章,以便对我们知识库中的所有文章以多种语言提供访问。翻译的文章可能存在词汇、句法和/或语法方面的错误。Microsoft 对由于内容的误译或客户对内容的使用所导致的任何不准确、错误或损失不承担责任。

点击这里察看该文章的英文版: 322022
这篇文章的 Microsoft Visual Basic.NET 版本,请参见 322025.
概要
本分步指南演示如何使用IEnumerableIEnumerator接口使您可以创建一个在foreach语句中使用的类。IEnumerableIEnumerator经常一起使用。虽然这些接口类似 (并且有相似的名称),它们具有不同的目的。

IEnumerator 接口

IEnumerator接口提供了一个集合,它是一个类的内部的迭代功能。IEnumerator需要实现以下三种方法:
  • MoveNext方法,按 1 递增的集合索引,并返回一个布尔值,该值指示是否已到达集合的末尾。
  • 重置方法,该方法将集合索引重置为其初始值为-1。这将使该枚举数无效。
  • 当前方法,它返回当前对象 [位置]。
      public bool MoveNext()      {         position++;         return (position < carlist.Length);      }      public void Reset()      {position = 0;}      public object Current      {         get { return carlist[position];}      }

IEnumerable 接口

IEnumerable接口foreach迭代提供支持。IEnumerable要求实现的GetEnumerator方法。
 public IEnumerator GetEnumerator()      {         return (IEnumerator)this;      }

何时使用哪个接口

最初,您可能会发现使用这些接口令人混淆。IEnumerator接口提供迭代通过集合类型对象类中。IEnumerable接口允许使用foreach循环的枚举。但是, IEnumerable接口的GetEmunerator方法返回的IEnumerator接口。因此,若要实现IEnumerable,还必须实现IEnumerator。如果不实现IEnumerator,不能强制转换为IEnumerator接口IEnumerableGetEnumerator方法的返回值。

总之, IEnumerable使用需要的类实现IEnumerator。如果您想要为foreach提供支持,实现两个接口。

逐个步骤示例

下面的示例演示如何使用这些接口。在此示例中,类名为汽车中使用IEnumeratorIEnumerable接口。汽车类有内部的汽车对象数组。由于这两个接口的实现中使用foreach构造的客户端应用程序可以枚举此内部数组。
  1. 请按照以下步骤创建新的控制台应用程序项目中 Visual C#:
    1. 开始 Microsoft Visual Studio.NET 或 Microsoft Visual Studio 2005。
    2. 文件菜单上,指向新建,然后单击项目
    3. 项目类型下单击Visual C# 项目,然后单击模板下的控制台应用程序

      注意:在 Visual Studio 2005 中,单击C#下的项目类型
    4. 名称框中,键入 ConsoleEnum.
  2. 为 host.cs,,然后将 host.cs 中的代码替换为以下代码:
    using System;namespace ConsoleEnum{  class host  {    [STAThread]    static void Main(string[] args)    {      cars C = new cars();      Console.WriteLine("\nInternal Collection (Unsorted - IEnumerable,Enumerator)\n");      foreach(car c in C)      Console.WriteLine(c.Make + "\t\t" + c.Year);       Console.ReadLine();    }  }}
  3. 项目菜单上,单击添加类,然后键入 汽车名称框中。
  4. Car.cs 中的代码替换为以下代码:
    using System;using System.Collections;namespace ConsoleEnum{     public class car   {    private int year;    private string make;            public car(string Make,int Year)    {      make=Make;      year=Year;    }    public int Year    {      get  {return year;}      set {year=value;}    }    public string Make    {      get {return make;}      set {make=value;}    }  }//end class}//end namespace
  5. 项目菜单上,单击添加类以添加到项目中,另一个类,然后键入 汽车名称框中。
  6. Cars.cs 中的代码替换为以下代码:
    using System;using System.Collections;namespace ConsoleEnum{   public class cars : IEnumerator,IEnumerable   {      private car[] carlist;      int position = -1;      //Create internal array in constructor.      public cars()      {         carlist= new car[6]      {         new car("Ford",1992),         new car("Fiat",1988),         new car("Buick",1932),         new car("Ford",1932),         new car("Dodge",1999),         new car("Honda",1977)      };      }      //IEnumerator and IEnumerable require these methods.      public IEnumerator GetEnumerator()      {         return (IEnumerator)this;      }      //IEnumerator      public bool MoveNext()      {         position++;         return (position < carlist.Length);      }      //IEnumerable      public void Reset()      {position = 0;}      //IEnumerable      public object Current      {         get { return carlist[position];}      }   }      }
  7. 运行该项目。注意到在控制台窗口中显示以下输出:
    Ford            1992Fiat            1988Buick           1932Ford            1932Dodge           1999Honda           1977

最佳做法

本文中的示例保持尽可能简单,以便更好地解释了如何使用这些接口。若要使代码更为可靠,以确保该代码使用当前的最佳实践指南,修改代码,如下所示:
  • 在嵌套类中实现IEnumerator ,以便您可以创建多个枚举数。
  • 提供异常处理当前IEnumerator方法。如果更改集合的内容,调用 reset 方法。因此,当前枚举数将失效,并且您收到 IndexOutOfRangeException 异常。其他情况下也可能导致此异常。因此,实现Try...捕捉块,以捕捉此异常并引发能反转异常。
using System;using System.Collections;namespace ConsoleEnum{  public class cars : IEnumerable  {    private car[] carlist;    //Create internal array in constructor.    public cars()    {      carlist= new car[6]    {      new car("Ford",1992),      new car("Fiat",1988),      new car("Buick",1932),      new car("Ford",1932),      new car("Dodge",1999),      new car("Honda",1977)    };    }        //private enumerator class        private class  MyEnumerator:IEnumerator        {          public car[] carlist;          int position = -1;        //constructor        public MyEnumerator(car[] list)        {          carlist=list;        }        private IEnumerator getEnumerator()        {          return (IEnumerator)this;        }                //IEnumerator        public bool MoveNext()        {          position++;          return (position < carlist.Length);        }        //IEnumerator        public void Reset()        {position = -1;}        //IEnumerator        public object Current        {          get           {             try             {              return carlist[position];            }                  catch (IndexOutOfRangeException)            {              throw new InvalidOperationException();            }          }        }      }  //end nested class    public IEnumerator GetEnumerator()    {      return new MyEnumerator(carlist);    }  }}

警告:本文已自动翻译

属性

文章 ID:322022 - 上次审阅时间:08/17/2015 06:26:00 - 修订版本: 5.0

Microsoft Visual C# 2005 Express Edition, Microsoft Visual C# .NET 2003 标准版, Microsoft Visual C# .NET 2002 标准版

  • kbhowtomaster kbmt KB322022 KbMtzh
反馈