zoukankan      html  css  js  c++  java
  • C# 枚举器

    1:枚举器和可枚举类型

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

    2:使用foreach语句

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

    例如下面的代码:

    1             int[] arr = { 1, 2, 3, 4, 5, 6 };
    2             foreach( 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语句

    自动做的事情。

    代码如下:

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

    程序运行的结果为

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

    IEnumerable接口

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

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

    如图所示:

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

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

    代码如下:

     1 using System;
     2 using System.Collections;
     3 
     4 namespace ConsoleApplication1
     5 {
     6     class Shape : IEnumerator
     7     {
     8         string[] _Shapes;
     9         int _Position = -1;
    10 
    11         public Shape(string[] _theShapes)
    12         {
    13             _Shapes = new string[_theShapes.Length];
    14             for( int i = 0; i < _theShapes.Length; i++ )
    15             {
    16                 _Shapes[i] = _theShapes[i];
    17             }
    18         }
    19 
    20         public Object Current
    21         {
    22             get
    23             {
    24                 if ( _Position == -1 )
    25                     throw new InvalidOperationException();
    26                 if (_Position >= _Shapes.Length)
    27                     throw new InvalidOperationException();
    28                 return _Shapes[_Position];
    29             }
    30         }
    31 
    32         public bool MoveNext()
    33         {
    34             if (_Position < _Shapes.Length - 1)
    35             {
    36                 _Position++;
    37                 return true;
    38             }
    39             else
    40                 return false;
    41         }
    42 
    43         public void Reset()
    44         {
    45             _Position = -1;
    46         }
    47     }
    48 
    49     class Component : IEnumerable
    50     {
    51         string[] shapes = { "Circular", "spherical", "Quadrilateral", "Label" };
    52         public IEnumerator GetEnumerator()
    53         {
    54             return new Shape( shapes );
    55         }
    56     }
    57 
    58     class Program
    59     {
    60         static void Main(string[] args)
    61         {
    62             Component comp = new Component();
    63             foreach ( string oshape in comp )
    64                 Console.WriteLine(oshape);
    65         }
    66        
    67     }
    68 }

    运行结果:

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

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

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

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

  • 相关阅读:
    C#反射(一)
    找回密码
    常用的webservice接口 .
    C# 反射应用技术
    Delphi简介
    C#程序思想简介
    如何跨线程访问window控件
    C#如何判断某个文件夹是否为共享,访问权限为只读
    Delphi基础
    Web Service接口
  • 原文地址:https://www.cnblogs.com/cxq0017/p/5844096.html
Copyright © 2011-2022 走看看