zoukankan      html  css  js  c++  java
  • C#知识点-枚举器和迭代器

    一、几个基本概念的理解

    问题一:为什么数组可以使用foreach输出各元素

    答:数组是可枚举类型,它实现了一个枚举器(enumerator)对象;枚举器知道各元素的次序并跟踪它们的位置,然后返回请求的当前项

    问题二:不用foreach能不能遍历各元素

    image

    问题三:什么是可枚举类

    答:可枚举类是指实现了IEnumerable接口的类;IEnumerable接口只有一个成员GetEnumerator方法,它返回对象的枚举器

    问题四:什么是枚举器

    答:实现了IEnumerator接口的枚举器包含三个函数成员:Current,MoveNext,Reset

    Current是只读属性,它返回object类型的引用;

    MoveNext是把枚举器位置前进到集合的下一项的方法,它返回布尔值,指示新的位置是否有效位置还是已经超过了序列的尾部;

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

    二、下面代码展示了一个可枚举类的完整示例

      1 namespace ConsoleApplication4
      2 {
      3     /// <summary>
      4     /// 自定义一个枚举对象
      5     /// </summary>
      6     class ColorEnumerator : IEnumerator
      7     {
      8         private string[] _colors;
      9         private int _position = -1;
     10 
     11         public ColorEnumerator(string[] arr)
     12         {
     13             _colors = arr;
     14             for (int i = 0; i < arr.Length; i++)
     15             {
     16                 _colors[i] = arr[i];
     17             }
     18         }
     19         public object Current
     20         {
     21             get
     22             {
     23                 if (_position == -1)
     24                 {
     25                     throw new InvalidOperationException();
     26                 }
     27                 if (_position >= _colors.Length)
     28                 {
     29                     throw new InvalidOperationException();
     30                 }
     31                 return _colors[_position];
     32             }
     33         }
     34 
     35         public bool MoveNext()
     36         {
     37             if (_position < _colors.Length - 1)
     38             {
     39                 _position++;
     40                 return true;
     41             }
     42             else
     43             {
     44                 return false;
     45             }
     46         }
     47 
     48         public void Reset()
     49         {
     50             _position = -1;
     51         }
     52     }
     53 
     54     /// <summary>
     55     /// 创建一个实现IEnumerable接口的枚举类
     56     /// </summary>
     57     class Spectrum : IEnumerable
     58     {
     59         private string[] Colors = { "red", "yellow", "blue" };
     60         public IEnumerator GetEnumerator()
     61         {
     62             return new ColorEnumerator(Colors);
     63         }
     64     }
     65 
     66     class Program
     67     {
     68         static void Main(string[] args)
     69         {
     70             Spectrum spectrum = new Spectrum();
     71             foreach (string color in spectrum)
     72             {
     73                 Console.WriteLine(color);
     74             }
     75             Console.ReadKey();
     76         }
     77     }
     78 }
     79 
    View Code

    三、泛型枚举接口

    IEnumerable<T>接口的GetEnumerator方法返回实现IEnumerator<T>的枚举类的实例;

    实现IEnumerator<T>的类实现了Current属性,它返回实际类型的对象,而不是object基类的引用;

    所以非泛型接口的实现不是类型安全的,因为还需要转换为实际类型。

    四、迭代器

    1.使用迭代器来创建枚举器

      1 namespace ConsoleApplication5
      2 {
      3     class MyClass
      4     {
      5         /// <summary>
      6         /// 获取一个迭代器
      7         /// </summary>
      8         /// <returns></returns>
      9         public IEnumerator<string> GetEnumerator()
     10         {
     11             return ColorEnumerator();
     12         }
     13         /// <summary>
     14         /// 迭代器
     15         /// </summary>
     16         /// <returns></returns>
     17         public IEnumerator<string> ColorEnumerator()
     18         {
     19             yield return "red";
     20             yield return "yellow";
     21             yield return "blue";
     22         } 
     23     }
     24     class Program
     25     {
     26         static void Main(string[] args)
     27         {
     28             MyClass mc = new MyClass();
     29             foreach (string color in mc)
     30             {
     31                 Console.WriteLine(color);
     32             }
     33             Console.ReadKey();
     34         }
     35     }
     36 }
    View Code

    2.使用迭代器来创建枚举类型

      1 namespace ConsoleApplication6
      2 {
      3     class MyClass
      4     {
      5         public IEnumerator<string> GetEnumerator()
      6         {
      7             //获取可枚举类型
      8             IEnumerable<string> enumerable = ColorEnumerable();
      9             //获取枚举器
     10             return ColorEnumerable().GetEnumerator();
     11         }
     12 
     13         public IEnumerable<string> ColorEnumerable()
     14         {
     15             yield return "red";
     16             yield return "yellow";
     17             yield return "blue";
     18         } 
     19     }
     20     class Program
     21     {
     22         static void Main(string[] args)
     23         {
     24             MyClass mc = new MyClass();
     25             //使用类对象
     26             foreach (string color in mc)
     27             {
     28                 Console.WriteLine(color);
     29             }
     30             Console.WriteLine("-----------------------");
     31             //使用类枚举器的方法
     32             foreach (string color in mc.ColorEnumerable())
     33             {
     34                 Console.WriteLine(color);
     35             }
     36             Console.ReadKey();
     37         }
     38     }
     39 }
    View Code

    3.产生多个可迭代类型

      1 namespace ConsoleApplication7
      2 {
      3     class MyClass
      4     {
      5         private string[] Colors = { "red", "yellow", "blue" };
      6         //顺序
      7         public IEnumerable<string> ColorOrder()
      8         {
      9             for (int i = 0; i < Colors.Length; i++)
     10             {
     11                 yield return Colors[i];
     12             }
     13         }
     14         //逆序
     15         public IEnumerable<string> ColorReversed()
     16         {
     17             for (int i = Colors.Length - 1; i >= 0; i--)
     18             {
     19                 yield return Colors[i];
     20             }
     21         }
     22     }
     23     class Program
     24     {
     25         static void Main(string[] args)
     26         {
     27             MyClass mc = new MyClass();
     28             foreach (string color in mc.ColorOrder())
     29             {
     30                 Console.WriteLine(color);
     31             }
     32             Console.WriteLine("------------------");
     33             foreach (string color in mc.ColorReversed())
     34             {
     35                 Console.WriteLine(color);
     36             }
     37             Console.ReadKey();
     38         }
     39     }
     40 }
     41 
    View Code
  • 相关阅读:
    I2C调试
    linux读取cpu温度
    看react全家桶+adtd有感
    react学习1(搭建脚手架,配置less,按需引入antd等)
    去掉console.log,正式环境不能有console.log
    Vue的minix
    数组去重我总结的最常用的方法,其他不常用就不写了
    inline-block bug解决方法
    vue中使用less/scss(这是2.0 3.0就不需要手动配置了只需要安装依赖就行了)
    Vue 调用微信扫一扫功能
  • 原文地址:https://www.cnblogs.com/kimisme/p/5538567.html
Copyright © 2011-2022 走看看