using System;
using System.Collections;
namespace EnumeratorAndEnumerable
{
///一、引言
//C#的Enumerator(枚举数) 和 Enumerable(可枚举类型)
//数组可以被foreach语句遍历数组中的元素,原因是数组可以按需提供一个叫做Enumerator(枚举数)的对象。Enumerator(枚举数)可以依次返回数组的元素。
//对于有Enumerator的类型而言,必须有一个方法来获取他们。在.Net中获取一个对象Enumerator的标准方法是调用对象的GetEnumerator()方法。
//实现了GetEnumerator方法的类型,叫做Enumerable(可枚举类型)
///二、Enumerator 和 Enumerable 的区别和联系
//Enumerator(枚举数)是可以依次返回集合项的类对象,Enumerable(可枚举类型)是带有GetEnumerator方法的类型,他返回Enumerator(枚举数)
//当foreach被用来遍历Enumerable(可枚举类型)时,他就会执行如下的行为:
// 1、通过调用Enumerable的GetEnumetator方法获取对象的Enumerator枚举数。
// 2、从枚举数中请求每一项并且把它作为迭代变量,代码可以读但不可以改变。
///三、可以用以下方式来实现枚举数
// 1、IEnumerator接口,IEnumerable接口,叫做非泛型接口形式
// 2、IEnumerator<T>,IEnumerable<T>,叫做泛型接口形式
// 3、不使用接口形式。
///四、IEnumerator接口包含3个函数成员:Current,MoveNext,Reset
// 4.1:Current 返回序列中当前项的属性,他是一个只读属性,返回Objeck类型的的引用,可以返回任何类型。
// 4.2:MoveNext 把枚举数位置前进到集合的下一项的方法,返回布尔值,指示新位置是有效位置还是已经超过了序列尾部,若超过返回false
// 4.3:Reset 方法把位重置为原始状态
/// <summary>
/// ///
/// </summary>
class Program
{
static void Main(string[] args)
{
int[] myArray = { 10,11,12,13};
//通过调用Enumerator 的MoveNext()方法和Current属性,手动遍历数组中的元素
Console.WriteLine("手动遍历元素:");
IEnumerator ie = myArray.GetEnumerator();
while (ie.MoveNext())//Enumerator的初始位置是-1,所以想要获取第一个元素就必须执行MoveNext()方法
{
Console.WriteLine((int)ie.Current);
}
//使用foreach直接进行遍历
Console.WriteLine("通过调用foreach直接获取数组元素:");
foreach (var i in myArray)
{
Console.WriteLine(i);
}
//枚举数类型
ColorEnumerator ce = new ColorEnumerator(new string[] { "Red", "Purple", "Yellow", "Blue" });
while (ce.MoveNext())
{
Console.WriteLine(ce.Current);
}
//如果要用foreach来遍历,就需要在定义一个Enumerable(可枚举类型)的类
Console.WriteLine("------------");
MyColorEnumerable me = new MyColorEnumerable();
foreach (var m in me)
{
Console.WriteLine(m);
}
Console.ReadLine();
}
}
/// <summary>
/// 定义一个保存颜色名称的 枚举数类
/// </summary>
class ColorEnumerator : IEnumerator
{
private string[] Colors;//颜色集合
/// <summary>
/// 初始位置
/// </summary>
private int Position = -1;
/// <summary>
/// 当前项
/// </summary>
public object Current
{
get {
if (Position == -1)
{
throw new InvalidOperationException();
}
if (Position == Colors.Length)
{
throw new InvalidOperationException();
}
return Colors[Position];
}
}
/// <summary>
/// 将位置移到集合的下一项
/// </summary>
/// <returns></returns>
public bool MoveNext()
{
if (Position < Colors.Length - 1)
{
Position++;
return true;
}
else
{
return false;
}
}
/// <summary>
/// 重置 集合的 位置
/// </summary>
public void Reset()
{
Position = -1;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="theColors"></param>
public ColorEnumerator(string[] theColors)
{
Colors = theColors;
}
}
/// <summary>
/// 定义 可枚举数类型 为ColorEnumerator实现foreach方法
/// </summary>
class MyColorEnumerable : IEnumerable
{
string[] MyColor = new string[] { "Red", "Purple", "Yellow", "Blue" };
public IEnumerator GetEnumerator()
{
return new ColorEnumerator(MyColor);
}
}
///五、总结
//如果想遍历一个对象中的所有元素,可以把对象设为枚举数类型(实现IEnumerator接口)和可枚举的类类型(实现IEnumerable接口)。
//前者需要实现IEnumerator接口的Current,MoveNewx,Reset成员函数,后者需要实现IEnumerable接口的GetEnumerable的成员函数,
//由于GetEnumerator的返回类型是IEnumerator对象,所以还要建立一个派生与IEnumerator的枚举数类,在这个类中实现Current,MoveNewx,Reset成员函数
//派生与IEnumerator的类可以使用foreach代码来遍历对象中的全部元素
}
using System.Collections;
namespace EnumeratorAndEnumerable
{
///一、引言
//C#的Enumerator(枚举数) 和 Enumerable(可枚举类型)
//数组可以被foreach语句遍历数组中的元素,原因是数组可以按需提供一个叫做Enumerator(枚举数)的对象。Enumerator(枚举数)可以依次返回数组的元素。
//对于有Enumerator的类型而言,必须有一个方法来获取他们。在.Net中获取一个对象Enumerator的标准方法是调用对象的GetEnumerator()方法。
//实现了GetEnumerator方法的类型,叫做Enumerable(可枚举类型)
///二、Enumerator 和 Enumerable 的区别和联系
//Enumerator(枚举数)是可以依次返回集合项的类对象,Enumerable(可枚举类型)是带有GetEnumerator方法的类型,他返回Enumerator(枚举数)
//当foreach被用来遍历Enumerable(可枚举类型)时,他就会执行如下的行为:
// 1、通过调用Enumerable的GetEnumetator方法获取对象的Enumerator枚举数。
// 2、从枚举数中请求每一项并且把它作为迭代变量,代码可以读但不可以改变。
///三、可以用以下方式来实现枚举数
// 1、IEnumerator接口,IEnumerable接口,叫做非泛型接口形式
// 2、IEnumerator<T>,IEnumerable<T>,叫做泛型接口形式
// 3、不使用接口形式。
///四、IEnumerator接口包含3个函数成员:Current,MoveNext,Reset
// 4.1:Current 返回序列中当前项的属性,他是一个只读属性,返回Objeck类型的的引用,可以返回任何类型。
// 4.2:MoveNext 把枚举数位置前进到集合的下一项的方法,返回布尔值,指示新位置是有效位置还是已经超过了序列尾部,若超过返回false
// 4.3:Reset 方法把位重置为原始状态
/// <summary>
/// ///
/// </summary>
class Program
{
static void Main(string[] args)
{
int[] myArray = { 10,11,12,13};
//通过调用Enumerator 的MoveNext()方法和Current属性,手动遍历数组中的元素
Console.WriteLine("手动遍历元素:");
IEnumerator ie = myArray.GetEnumerator();
while (ie.MoveNext())//Enumerator的初始位置是-1,所以想要获取第一个元素就必须执行MoveNext()方法
{
Console.WriteLine((int)ie.Current);
}
//使用foreach直接进行遍历
Console.WriteLine("通过调用foreach直接获取数组元素:");
foreach (var i in myArray)
{
Console.WriteLine(i);
}
//枚举数类型
ColorEnumerator ce = new ColorEnumerator(new string[] { "Red", "Purple", "Yellow", "Blue" });
while (ce.MoveNext())
{
Console.WriteLine(ce.Current);
}
//如果要用foreach来遍历,就需要在定义一个Enumerable(可枚举类型)的类
Console.WriteLine("------------");
MyColorEnumerable me = new MyColorEnumerable();
foreach (var m in me)
{
Console.WriteLine(m);
}
Console.ReadLine();
}
}
/// <summary>
/// 定义一个保存颜色名称的 枚举数类
/// </summary>
class ColorEnumerator : IEnumerator
{
private string[] Colors;//颜色集合
/// <summary>
/// 初始位置
/// </summary>
private int Position = -1;
/// <summary>
/// 当前项
/// </summary>
public object Current
{
get {
if (Position == -1)
{
throw new InvalidOperationException();
}
if (Position == Colors.Length)
{
throw new InvalidOperationException();
}
return Colors[Position];
}
}
/// <summary>
/// 将位置移到集合的下一项
/// </summary>
/// <returns></returns>
public bool MoveNext()
{
if (Position < Colors.Length - 1)
{
Position++;
return true;
}
else
{
return false;
}
}
/// <summary>
/// 重置 集合的 位置
/// </summary>
public void Reset()
{
Position = -1;
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="theColors"></param>
public ColorEnumerator(string[] theColors)
{
Colors = theColors;
}
}
/// <summary>
/// 定义 可枚举数类型 为ColorEnumerator实现foreach方法
/// </summary>
class MyColorEnumerable : IEnumerable
{
string[] MyColor = new string[] { "Red", "Purple", "Yellow", "Blue" };
public IEnumerator GetEnumerator()
{
return new ColorEnumerator(MyColor);
}
}
///五、总结
//如果想遍历一个对象中的所有元素,可以把对象设为枚举数类型(实现IEnumerator接口)和可枚举的类类型(实现IEnumerable接口)。
//前者需要实现IEnumerator接口的Current,MoveNewx,Reset成员函数,后者需要实现IEnumerable接口的GetEnumerable的成员函数,
//由于GetEnumerator的返回类型是IEnumerator对象,所以还要建立一个派生与IEnumerator的枚举数类,在这个类中实现Current,MoveNewx,Reset成员函数
//派生与IEnumerator的类可以使用foreach代码来遍历对象中的全部元素
}