C# 枚举器

1:枚举器和可枚举类型

我们知道使用foreach可以遍历数组中的元素。那么为什么数组可以被foreach语句处理呢,下面我们就进行讨论一下这个问题。

2:使用foreach语句

我们知道当我们使用foreach语句的时候,这个语句为我们依次取出了数组中的每一个元素。

例如下面的代码:

1int[] arr = { 1, 2, 3, 4, 5, 6 };2foreach( int arry in arr )3            {4                 Console.WriteLine("Array Value::{0}",arry);5             }

输出效果为

 为什么数组可以使用foreach来遍历,原因是数组可以按需提供一个叫做枚举器(enumerator)的对象,枚举器可以依次返回请求的数组中的元素,枚举器知道项的次序并且跟踪它在序列中的位置。依次返回请求的当前项。

  对于有枚举器的类型而言,必须有一个方法来获取它这个类型。获取一个对象枚举器的方法是调用对象的GetEnumrator方法,实现GetEnumrator方法的类型叫做可枚举类型。那么数组就是可枚举类型。

  下图演示一下可枚举类型和枚举器之间的关系。

foreach结构设计用来和可枚举类型一起使用,只要给它的遍历对象是可枚举类型,比如数组。

1:通过调用GetEnumrator方法获取对象的枚举器。

2:从枚举器中请求每一项并且把它作为迭代器,代码可以读取该变量,但不可以改变

 foreach(Type VarName in EnumrableObject )

{

  ...

}

EnumrableObjec必须是可枚举类型。

2:IEnumrator接口

IEnumrator接口包含了3个函数成员:Current、MoveNext以及Reset;

.Current是返回序列中当前位置项的属性。(注意:Current它是只读属性,它返回Object类型的引用,所以可以返回任意类型)

.MoveNext是把枚举器位置前进到集合中下一项的方法。它也但会布尔值,指示新的位置是否是有效位置。

注:如果返回的位置是有效的,方法返回true;

  如果新的位置是无效的,方法返回false;

  枚举器的原始位置在序列中的第一项之前,因此MoveNext必须在第一次使用Current之前调用。

.Reset是把位置重置为原始状态的方法。

 下面我们用图表示一下他们之间的关系

有了集合的枚举器,我们就可以使用MoveNext和Current成员来模仿foreach循环遍历集合中的项,例如,我们已经知道数组是可枚举类型,所以下面的代码手动做foreach语句

自动做的事情。

代码如下:

复制代码
 1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.Collections; 7 8namespace ConsoleApplication1 9{10class Program11    {12staticvoid Main(string[] args)13        {14int[] arr = { 1, 2, 3, 4, 5, 6 };15             IEnumerator ie = arr.GetEnumerator();16while( ie.MoveNext() )17            {18int i = (int)ie.Current;19                 Console.WriteLine("{0}", i);20            }21        }22    }23 }
复制代码

程序运行的结果为

我们来用图解释一下代码中的数组结构

IEnumerable接口

数组是可枚举类型,是因为实现了IEnumerable接口的类,所以可枚举类都是因为实现了IEnumerable接口的类。

IEnumerable接口只有一个成员——GetEnumerator()方法,它返回对象的枚举器。

如图所示:

下面我们举一个使用IEnumerator和IEnumerable的例子

下面的代码展示了一个可枚举类的完整示例,该类叫Component(球形)。它的枚举器类为Shape(形状)。

代码如下:

复制代码
 1using System; 2using System.Collections; 3 4namespace ConsoleApplication1 5{ 6class Shape : IEnumerator 7    { 8string[] _Shapes; 9int _Position = -1;1011public Shape(string[] _theShapes)12        {13             _Shapes = newstring[_theShapes.Length];14for( int i = 0; i < _theShapes.Length; i++ )15            {16                 _Shapes[i] = _theShapes[i];17            }18        }1920public Object Current21        {22get23            {24if ( _Position == -1 )25thrownew InvalidOperationException();26if (_Position >= _Shapes.Length)27thrownew InvalidOperationException();28return _Shapes[_Position];29            }30        }3132publicbool MoveNext()33        {34if (_Position < _Shapes.Length - 1)35            {36                 _Position++;37returntrue;38            }39else40returnfalse;41        }4243publicvoid Reset()44        {45             _Position = -1;46        }47    }4849class Component : IEnumerable50    {51string[] shapes = { "Circular", "spherical", "Quadrilateral", "Label" };52public IEnumerator GetEnumerator()53        {54returnnew Shape( shapes );55        }56    }5758class Program59    {60staticvoid Main(string[] args)61        {62             Component comp = new Component();63foreach ( string oshape in comp )64                Console.WriteLine(oshape);65        }6667    }68 }
复制代码

运行结果:

如果您看了本篇博客,觉得对您有所收获,请点击右下角的 [推荐]

如果您想转载本博客,请注明出处

如果您对本文有意见或者建议,欢迎留言

感谢您的阅读,请关注我的后续博客

你可能感兴趣的:(C#,WPF,C#,IEnumrator)