现在的位置: 首页 > 综合 > 正文

如何使 Visual C# 类 foreach 语句中可用

2012年07月22日 ⁄ 综合 ⁄ 共 4397字 ⁄ 字号 评论关闭

如何使 Visual C# 类 foreach 语句中可用

注意:这篇文章是由无人工介入的自动的机器翻译系统翻译完成。这些文章是微软为不懂英语的用户提供的, 以使他们能够理解这些文章的内容。微软不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的使用所引起的任何直接的, 或间接的可能的问题负责。
文章编号 : 322022
最后修改 : 2006年12月11日
修订 : 2.1
有关与本文, MicrosoftVisualBasic.NET 版本请参阅 322025 (http://support.microsoft.com/kb/322025/) .


概要

本分步指南演示如何使用 IEnumerable 和 IEnumerator 接口来 foreach 语句中创建一个类, 可用。 IEnumerable 和 IEnumerator 经常用在一起。 虽然这些接口很相似 (和具有类似名称), 它们具有不同用途。

回到顶端

IEnumerator 接口


IEnumerator 接口提供了对于是内部使用类集合迭代功能。 IEnumerator 要求您实现三种方法:

MoveNext 方法, 按 1 递增集合索引并返回表明是否达到集合末尾 bool。
Reset 方法, 其中重置为其初始值为 - 1 集合索引。 这会使枚举。
当前 方法, 它返回处 ] [ 当前对象。

      public bool MoveNext()
      {
         position++;
         return (position < carlist.Length);
      }

      public void Reset()
      {position = 0;}

      public object Current
      {
         get { return carlist[position];}
      }

回到顶端

IEnumerable 接口


为 foreach 迭代 IEnumerable 接口提供支持。 IEnumerable 要求实现 GetEnumerator 方法。

 public IEnumerator GetEnumerator()
      {
         return (IEnumerator)this;
      }

回到顶端

何时使用哪些接口


最初, 您可能发现混乱要使用这些接口。 迭代 IEnumerator 接口提供了到类中集合类型对象。 通过使用一个 foreach 循环 IEnumerable 接口允许枚举。 但是, GetEmunerator 方法的 IEnumerable 接口返回 IEnumerator 接口。 因此, 来实现 IEnumerable , 还必须实现 IEnumerator 。 如果您不实现 IEnumerator , 您不能转换到 IEnumerator 接口从 IEnumerable 的 GetEnumerator 方法返回值。

在摘要, 使用 IEnumerable 需要类实现 IEnumerator 。 如果要提供支持对于 foreach , 实现两个接口。

回到顶端

按步骤示例步骤


以下示例说明如何使用这些接口。 在本示例, 命名 汽车 类中使用 IEnumerator 和 IEnumerable 接口。 汽车 类具有内部 汽车 对象数组。 客户端应用程序可通过此内部阵列枚举因实现了以下两个接口通过 foreach 构造。

1. 请执行这些步骤以 Visual C# 中新建控制台应用程序项目:

a. 启动 MicrosoftVisualStudio.NET 或 Microsoft Visual Studio 2005。
b. 在 文件 菜单, 指向 新建 , 然后单击 项目 。
c. 单击 项目类型 , 下 VisualC # 项目 , 然后单击 模板 下 控制台应用程序 。

注意 对于 Visual Studio 2005, 单击 项目类型 VisualC #

d. 在 名称 框中, 键入 ConsoleEnum 。
2. 重命名为 host.cs, Class, 然后用以下代码替换 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. 在 项目 菜单上, 单击 AddClass@@@ , 并在 名称 框中键入 汽车 。
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. 在 项目 菜单上, 单击 AddClass@@@ 将其他类添加到项目, 并在 名称 框中键入 汽车 。
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            1992
Fiat            1988
Buick           1932
Ford            1932
Dodge           1999
Honda           1977

回到顶端

最佳做法


本文中示例保持尽可能简单, 好解释使用这些接口。 若要使代码更可靠并以确保代码使用当前最佳做法原则, 如下修改代码:

在嵌套类实现 IEnumerator 以便您可以创建多个枚举。
提供对 当前 方法是 IEnumerator 处理异常。 如果集合的内容更改, 重置方法。 因此, 将失效当前枚举, 并收到一个 IndexOutOfRangeException 异常。 其他情况也可能导致此异常。 因此, 实现 Try...Catch 块来捕捉此异常与引发 InvalidOperationException 异常。

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);
    }
  }
}

回到顶端

抱歉!评论已关闭.