数组可以被foreach语句遍历数组中的元素,原因是数组可以按需提供一个叫做枚举数(enumerator)的对象.枚举数可以依次返回请求的数组的元素.
对于有枚举数的类型而言,必须有一个方法来获取它们.在.NET中获取一个对象枚举数的标准用法是调用对象的GetEnumerator方法.实现GetEnumerator方法的类型叫做可枚举类型(enumerable),数组就是可枚举类型.
要注意枚举数(enumerator)和可枚举类型(enumerable)的区别和联系.
枚举数是可以依次返回集合项的类对象,可枚举类型是带有GetEnumerator方法的类型,它返回枚举数.
当foreach被用来遍历可枚举类型时,它就会执行如下的行为:
1,通过调用GetEnumerator方法获取对象的枚举数.
2,从枚举数中请求每一项并且把它作为迭代变量,代码可以读但不可以改变.

枚举数共有3种,可以用以下方式来实现枚举数:
1 IEnumerator/IEnumerable接口 ,叫做非泛型接口形式.
2 IEnumerator<T>/IEnumerable<T>接口, 叫做泛型接口形式.
3 不使用接口形式.
IEnumerator接口
IEnumerator接口包含3个函数成员:Current,MoveNext,Reset
Current返回序列中当前项的属性,它是一个只读属性.返回object类型的引用,所以可以返回任何类型.
MoveNext是把枚举数位置前进到集合的下一项的方法,它返回布尔值,指示新位置是有效位置还是已经超过了序列的尾部.如果是已经到达了尾部,则返回false.
Reset方法把位置重置为原始状态.
查看下面的代码:

int[] MyArray = { 10, 11, 12, 13 }; //创建数组
IEnumerator ie = MyArray.GetEnumerator(); //获取枚举数
while (ie.MoveNext()) //移到下一项
Console.WriteLine((int)ie.Current); //获取当前项并输入
枚举数的初始位置是-1,所以要想获取第一个元素就必须执行MoveNext()方法.
上面的代码就是调用枚举数的Current和MoveNext成员函数手工地遍历数组中的元素.
或者可以直接使用foreach直接获取:
foreach(int i in MyArray)
Console.WriteLine(i);
下面列出一个颜色名数组的枚举数类:
using System.Collections;

class ColorEnumerator : IEnumerator
{
private string[] Colors;
private int Position = -1;
public object Current
{
get
{
if (Position == -1)
throw new InvalidOperationException();
if (Position == Colors.Length)
throw new InvalidOperationException(); ;
return Colors[Position];
}
}
public bool MoveNext()
{
if (Position < Colors.Length - 1)
{
Position ++;
return true;
}
else
return false;
}

public void Reset()
{
Position = -1;
}
public ColorEnumerator(string[] theColors) //构造函数
{
Colors = new string[theColors.Length];
for (int i = 0; i < theColors.Length - 1; i++)
Colors[i] = theColors[i];
}
}

以上代码就构造了一个完整的枚举数类型.下面生成对象返回枚举数.
class Program
{
static void Main()
{
ColorEnumerator ce = new ColorEnumerator(new string[]{"yellow","red","white","black"});
while (ce.MoveNext())
Console.WriteLine((string)(ce.Current));
Console.ReadKey();
}
}
如果要用foreach来遍历枚举数,需要再定义一个可枚举类型的类,这个类要实现IEnumerable接口的功能.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}

class MyEnumerable : IEnumerable //定义一个可枚举类型的类
{
string[] MyColor = new string[] { "yellow", "red", "black", "white" };
public IEnumerator GetEnumerator()    //实现接口       
{
return new ColorEnumerator(MyColor); //返回一个枚举数的对象
}
}
现在就可以使用foreach来遍历可枚举类型对象的所有元素了.
class Program
{
static void Main()
{
MyEnumerable me = new MyEnumerable();
foreach (string i in me)
Console.WriteLine(i);
Console.ReadKey();
}
}

总结一下,如果想遍历一个对象中的所有元素,可以把对象设为枚举数类型(实现IEnumerator接口)和可枚举的类类型(实现IEnumerable接口),前者需要实现IEnumerator接口的Current,MoveNext和Rest成员函数,后者需要实现IEnumerable接口的GetEnumerator成员函数,由于GetEnumerator返回的是IEnumerator对象,所以还要建立一个派生于IEnumerator的枚举数类,在这个类中实现Current,MoveNext和Reset成员函数.派生于IEnumerable的类可以使用foreach代码来遍历对象中的全部元素.

C#的枚举数(Enumerator)和可枚举类型(Enumerable)相关推荐

  1. C#的Enumerator(枚举数) 和 Enumerable(可枚举类型)

    using System; using System.Collections; namespace EnumeratorAndEnumerable {     ///一.引言     //C#的Enu ...

  2. c语言枚举法在单片机的应用,小学三年级奥数 第七讲 枚举法(一)(学生版).doc

    第七讲 枚举法(一) 学习内容:用枚举法一一列举可能的情况 学习目标:1.做到不重补漏,把复杂的问题简单化 2.按照一定的规律,特点去枚举 3.从思想上认识到枚举的重要性 课题引入 枚举法是一种常见的 ...

  3. 集合在枚举数实例化后进行了修改_(编程知识)C# 枚举与位枚举

    一.枚举的概念: C# 枚举(Enum), 枚举类型是用于声明一组命名的常数的基本数据类型(值类型): 二.枚举的定义: 声明 enum 变量: enum {enumeration list}; 其中 ...

  4. C# 枚举类型Enumerable及其扩展

    C# 枚举类型Enumerable及其扩展 重要的数据类型 枚举类型是编程里重要的一种数据类型,了解其本质和扩展类型的使用方法,将有助于解决编程中遇到的数据处理问题. IEnumerable接口 实现 ...

  5. c语言枚举法课程设计报告,枚举法的程序实现及优化

    计新明 内容分析 本部分内容是教育科学出版社出版的必修1<数据与计算>第四单元第一节中的内容,整本书的思路是初始数据与计算.编程计算.认识数据.计算与问题解决.数据分析与人工智能,第四章属 ...

  6. C语言基本数据类型笔记整理(整型、实型/浮点型、字符型、枚举型、构造类型、指针类型、空类型)

    C语言基本数据类型 一.整型 ①有符号整型 ②无符号整型 二.实型 三.字符型 四.枚举型 五.构造类型 ①数组 ②结构体 ③共用体 六.指针类型 七.空类型 一.整型 ①有符号整型 有符号整型 关键 ...

  7. java 枚举使用简书_java枚举类型使用和详解

    1.定义 An enum type is a special data type that enables for a variable to be a set of predefined const ...

  8. java 枚举迭代_Java中的枚举和迭代器之间的区别

    java 枚举迭代 Java中的枚举与迭代器 (Enumeration vs Iterator in Java) Here, we will see how Enumeration differs f ...

  9. java 枚举_深入理解Java枚举

    所有知识体系文章,[GitHub](https://github.com/Ziphtracks/JavaLearningmanual)已收录,欢迎Star!再次感谢,愿你早日进入大厂! https:/ ...

最新文章

  1. Linux Shell高级技巧(目录)
  2. 少标签数据学习,54页ppt
  3. 《数学之美》第4章 谈谈分词
  4. suse 12sp1 oracle 11g r2 时出现错误 调用/sysman/lib/ins_emagent.mk的目标nmo时出错
  5. 面试官:你相信光吗?
  6. C++ 用vector创建数组对象
  7. 【杂谈】如何从数据准备,模型设计与调优,训练到部署完成整个深度学习算法流程...
  8. centos7 安装git_Gitlab安装及使用
  9. hiveserver2启动不起来_汽车一键启动只能用来打火吗 车主必须知道的几个“隐藏”技巧!...
  10. win2008r2 惠普g160鼠标_分享 HP 原机附带 WIN2008 R2 标准版 64位
  11. opengl 旋转矩阵和纹理坐标相乘_OpenGL-Rotating Points
  12. java将Map转换为List
  13. 学习笔记——矩阵键盘的扫描原理与基本应用
  14. 一文搞懂HTTP协议(带图文)
  15. find+sed考试题及生产实战解决案例分享(考试答案系列)
  16. Snaker 用户手册
  17. Golang学习(十五) 数组排序和二分查找
  18. 墨者学院tomcat后台弱口令漏洞利用
  19. 通过快递鸟如何接入圆通速递电子面单
  20. C++,Linux架构师成长之路

热门文章

  1. IoU系列(IoU, GIoU, DIoU, CIoU)
  2. php订单系统 帝国cms,帝国cms有订单管理系统吗
  3. 白皮书 | 智慧公路体系架构、关键技术、生态体系及建设实践
  4. 【转】地盘被HTML5蚕食 Flash前途堪忧
  5. opencv python安装 centos_centos下安装opencv
  6. 实验二十五——IEEE 802.11p和VANET仿真
  7. 【论文解读】LaneNet 基于实体分割的端到端车道线检测
  8. faster-rcnn 之 RPN网络的结构解析
  9. tf.keras.activations.gelu tensorflow1.15.0
  10. spring面试题目