本分步指南演示如何使用 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);
}
}
}
回到顶端