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

using System;
using System.Collections;


namespace EnumeratorAndEnumerable
{
    ///////一、引言
    //C#的Enumerator(枚举数) 和 Enumerable(可枚举类型)
    //数组可以被foreach语句遍历数组中的元素,原因是数组可以按需提供一个叫做Enumerator(枚举数)的对象。Enumerator(枚举数)可以依次返回数组的元素。
    //对于有Enumerator的类型而言,必须有一个方法来获取他们。在.Net中获取一个对象Enumerator的标准方法是调用对象的GetEnumerator()方法。
    //实现了GetEnumerator方法的类型,叫做Enumerable(可枚举类型)
    ///////二、Enumerator 和 Enumerable 的区别和联系
    //Enumerator(枚举数)是可以依次返回集合项的类对象,Enumerable(可枚举类型)是带有GetEnumerator方法的类型,他返回Enumerator(枚举数)
    //当foreach被用来遍历Enumerable(可枚举类型)时,他就会执行如下的行为:
    //  1、通过调用Enumerable的GetEnumetator方法获取对象的Enumerator枚举数。
    //  2、从枚举数中请求每一项并且把它作为迭代变量,代码可以读但不可以改变。
    ///////三、可以用以下方式来实现枚举数
    //  1、IEnumerator接口,IEnumerable接口,叫做非泛型接口形式
    //  2、IEnumerator<T>,IEnumerable<T>,叫做泛型接口形式
    //  3、不使用接口形式。


    ///////四、IEnumerator接口包含3个函数成员:Current,MoveNext,Reset
    //         4.1:Current 返回序列中当前项的属性,他是一个只读属性,返回Objeck类型的的引用,可以返回任何类型。
    //         4.2:MoveNext 把枚举数位置前进到集合的下一项的方法,返回布尔值,指示新位置是有效位置还是已经超过了序列尾部,若超过返回false
    //         4.3:Reset 方法把位重置为原始状态
    /// <summary>
    /// ///
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            ////int[] myArray = { 10,11,12,13};
            //////通过调用Enumerator 的MoveNext()方法和Current属性,手动遍历数组中的元素
            ////Console.WriteLine("手动遍历元素:");
            ////IEnumerator ie = myArray.GetEnumerator();
            ////while (ie.MoveNext())//Enumerator的初始位置是-1,所以想要获取第一个元素就必须执行MoveNext()方法
            ////{
            ////    Console.WriteLine((int)ie.Current);
            ////}
            //////使用foreach直接进行遍历
            ////Console.WriteLine("通过调用foreach直接获取数组元素:");
            ////foreach (var i in myArray)
            ////{
            ////    Console.WriteLine(i);
            ////}


            //枚举数类型
            ColorEnumerator ce = new ColorEnumerator(new string[] { "Red", "Purple", "Yellow", "Blue" });
            while (ce.MoveNext())
            {
                Console.WriteLine(ce.Current);
            }
            //如果要用foreach来遍历,就需要在定义一个Enumerable(可枚举类型)的类
            Console.WriteLine("------------");
            MyColorEnumerable me = new MyColorEnumerable();
            foreach (var m in me)
            {
                Console.WriteLine(m);
            }
            Console.ReadLine();
        }
    }


    /// <summary>
    /// 定义一个保存颜色名称的  枚举数类
    /// </summary>
    class ColorEnumerator : IEnumerator
    {
        private string[] Colors;//颜色集合
        /// <summary>
        /// 初始位置
        /// </summary>
        private int Position = -1;
        /// <summary>
        /// 当前项
        /// </summary>
        public object Current
        {
            get {
                if (Position == -1)
                {
                    throw new InvalidOperationException();
                }
                if (Position == Colors.Length)
                {
                    throw new InvalidOperationException();
                }
                return Colors[Position];
            }
        }


        /// <summary>
        /// 将位置移到集合的下一项
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            if (Position < Colors.Length - 1)
            {
                Position++;
                return true;
            }
            else
            {
                return false;
            }
        }


        /// <summary>
        /// 重置 集合的 位置
        /// </summary>
        public void Reset()
        {
            Position = -1;
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="theColors"></param>
        public ColorEnumerator(string[] theColors)
        {
            Colors = theColors;
        }
    }


    /// <summary>
    /// 定义 可枚举数类型 为ColorEnumerator实现foreach方法
    /// </summary>
    class MyColorEnumerable : IEnumerable
    {
        string[] MyColor = new string[] { "Red", "Purple", "Yellow", "Blue" };


        public IEnumerator GetEnumerator()
        {
            return new ColorEnumerator(MyColor);
        }
    }


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




}

猜你喜欢

转载自blog.csdn.net/qq_39081464/article/details/81016167