C#知识点-枚举器和迭代器

一、几个基本概念的理解

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

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

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

问题三:什么是可枚举类

答:可枚举类是指实现了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 

三、泛型枚举接口

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 }

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 }

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 

时间: 2024-10-26 01:37:09

C#知识点-枚举器和迭代器的相关文章

设计模式 - 适配器模式(adapter pattern) 枚举器和迭代器 详解

适配器模式(adapter pattern) 枚举器和迭代器 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考适配器模式(adapter pattern): http://blog.csdn.net/caroline_wendy/article/category/2281679 Java早期版本的枚举器(Enumeration)和现在的迭代器(Iterator) 可以使用适配器(adapter)进行转换. 适配器(adapter)代码: /** *

设计模式 - 适配器模式(adapter pattern) 枚举器和迭代器 具体解释

适配器模式(adapter pattern) 枚举器和迭代器 具体解释 本文地址: http://blog.csdn.net/caroline_wendy 參考适配器模式(adapter pattern): http://blog.csdn.net/caroline_wendy/article/category/2281679 Java早期版本号的枚举器(Enumeration)和如今的迭代器(Iterator) 能够使用适配器(adapter)进行转换. 适配器(adapter)代码: /**

枚举器和迭代器

一.枚举器和可枚举类型 1.0   一个简单的例子 1 static void Main(string[] args) 2 { 3 int[] arr = { 2,3,5,8}; 4 foreach (int item in arr) 5 { 6 Console.WriteLine("item's Value is :{0}",item); 7 } 8 Console.ReadKey(); 9 } 上边例子通过foreach依次取出数组中的元素并打印,为什么数组能够实现这种操作呢?原因

C#枚举器和迭代器

Foreach能够获取数组中的每一个元素,原因数组能够提供一个枚举器的对象.对于枚举器类型而言,必须有一个方法来获取它.获取一个对象枚举器的方法是调用对象的GetEnumerator方法.数组是可枚举类型. IEnumerator接口: 实现了IEnumerator接口的枚举器包含了Current.MoveNext以及Reset函数成员. Current是返回序列中当前位置的属性: 它是只读属性. 它返回object类型的引用,所以可以返回任何类型 MoveNext是枚举器位置前进到下一项的方法

ruby迭代器枚举器

迭代器一个迭代器是一个方法,这个方法里面有yield语句,使用了yield的方法叫做迭代器,迭代器并非一定要迭代,与传递给这个方法的块进行数据传输 yield将数据传给代码快,代码块再把数据传输给yield each方法就是一个迭代器,里面有yield语句 枚举器1 一个枚举器是Enumerable::Enumerator的一个对象,Enumerable是一个模块2 使用枚举器 1.8的时候需要 require 'enumerator',在2.1就不用了3 可以通过new来实例化一个枚举器,但是

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}

IEnumerable公开枚举器

// 摘要: //     公开枚举器,该枚举器支持在非泛型集合上进行简单迭代. [ComVisible(true)] [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")] public interface IEnumerable { // 摘要: //     返回一个循环访问集合的枚举器. // // 返回结果: //     可用于循环访问集合的 System.Collections.IEnumerator 对象. [DispId(-4)]

4)装饰器、迭代器、生成器以及内置函数

 装饰器.迭代器.生成器以及内置函数 装饰器: 原函数前后增加功能,切不改变函数的原本使用方式 import timedef wrapper(f):    def inner():        start = time.time()        f()        end = time.time()        print('执行效率为%s'%(end-start))    return inner @wrapperdef func():    print('this is func')

for..in遍历,枚举器

#pragma mark ------------for循环遍历集合中的元素------ //创建一个数组,包含5个字符串对象,倒序取出数组中的所有元素,并存储到另一可变数组中 NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; NSMutableArray *marray = [NSMutableArray arrayWithCapacity:0]; for