zoukankan      html  css  js  c++  java
  • C#的枚举数(Enumerator)和可枚举类型(Enumerable)

    http://sywxy.iteye.com/blog/1317750

    数组可以被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代码来遍历对象中的全部元素

  • 相关阅读:
    WPF自定义路由事件
    一文看懂微服务背后的技术演进与应用实践
    云原生消息、事件、流超融合平台——RocketMQ 5.0 初探
    KubeVela 1.1 发布,开启混合环境应用交付新里程碑
    Facebook宕机背后,我们该如何及时发现DNS问题
    Apache Flink 在汽车之家的应用与实践
    新一代容器平台ACK Anywhere,来了
    Serverless 工程实践 | Serverless 应用优化与调试秘诀
    OpenKruise 如何实现应用的可用性防护?
    国家网络安全宣传周:勒索病毒利如刀,上网备好技能包
  • 原文地址:https://www.cnblogs.com/opop/p/5556864.html
Copyright © 2011-2022 走看看