zoukankan      html  css  js  c++  java
  • C#如何实现自定义集合的IEnumerable 和 IEnumerator 接口并使用foreach访问自定义集合

       抛砖引玉:                                                                                         

    static void Main(string[] args)
    {
        int[] array = new int[] { 5,4,3,2,1};
        foreach (int i in array)
            Console.WriteLine("Number:"+i);
        Console.ReadKey();            
    }
    /**
     * -------------执行结果-------------
     * Number:5
     * Number:4
     * Number:3
     * Number:2
     * Number:1
     * -------------执行结果-------------
     */

    问题:为什么使用foreach可以遍历出数组中的所有元素呢?                  

    原因:数组是可枚举类型,它可以按需提供枚举数,枚举数可以依次返回请求的数组的元素。而foreach结构被设计用来和可枚举类型一起使用,只要给foreach的遍历对象是可枚举类型,则她就会执行如下行为:

    1. 通过调用GetEnumerator方法获取对象(如:数组)的枚举数(即数组中的元素值)
    2. 从枚举数中请求每一项并把她作为迭代遍历

    因为数组是可枚举类型,所以我就使用使用IEnumerator接口来实现枚举数以模仿foreach的循环遍历

    实现代码如下:

    static void Main(string[] args)
    {
        int[] array = new int[] { 5,4,3,2,1};
        IEnumerator ie = array.GetEnumerator();//获取枚举数
        while (ie.MoveNext())//移动下一项
        {
            //最初,枚举数定位在集合中第一个元素前,在此位置上,Current 属性未定义
            //因此,在读取 Current 的值之前,必须调用 MoveNext 方法将枚举数提前到集合的第一个元素
            int i = (int)ie.Current;//获取当前项
            Console.WriteLine("Number:" + i);
        }      
    }
       /**
        * -------------执行结果-------------
        * Number:5
        * Number:4
        * Number:3
        * Number:2
        * Number:1
        * -------------执行结果-------------
        */

    实现IEnumerable 和 IEnumerator 接口                                                                    

    以下示例演示如何实现自定义集合的IEnumerable 和 IEnumerator 接口,在此示例中,没有显式调用这些接口的成员,但实现了它们,以便支持使用 foreach循环访问该集合

    要点:

    1. 显示实现IEnumerable接口的GetEnumerator成员函数
    2. 显示实现IEnumerator接口的Current,Reset(),MoveNext()

    示意图:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {    
        // 实现IEnumerator接口
        public class PersonIEnumerator : IEnumerator
        {
            string[] Person;
            int position = -1;
            public PersonIEnumerator(string[] thePersons)
            {
                Person = new string[thePersons.Length];
                for (int i = 0; i < thePersons.Length; i++)
                {
                    Person[i] = thePersons[i];
                }
            }
            //IEnumerator接口的特性1
            public object Current
            {
                get { return Person[position]; }
            }
            //IEnumerator接口的特性2
            public bool MoveNext()
            {
                if (position < Person.Length - 1)
                {
                    position++;
                    return true;
                }
                else
                    return false;
            }
            //IEnumerator接口的特性3
            public void Reset()
            {
                position = -1;
            }
        }
        //实现IEnumerable接口
        public class MyPersons : IEnumerable
        {
            string[] strArr = new string[] { "周星驰", "莫言", "贝克汉姆", "林志颖" };
            //返回IEnumerator类型的对象
            public IEnumerator GetEnumerator()
            {
                return new PersonIEnumerator(strArr);
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                MyPersons mp = new MyPersons();
                foreach (string name in mp)
                {
                    Console.WriteLine("{0}", name);
                }
                Console.ReadKey();            
            }        
        }
        /**
         * -------------执行结果-------------
         * 周星驰
         * 莫言
         * 贝克汉姆
         * 林志颖
         * -------------执行结果-------------
         */
    }

    注:C# 语言的 foreach 语句隐藏了枚举数的复杂性。因此,建议使用 foreach,而不直接操作枚举数

    原创文章,转载请注明出处:http://www.cnblogs.com/hongfei

  • 相关阅读:
    php防止刷流量攻击
    PHP序列化变量的4种方法
    php递归操作目录 递归对参数转义
    php 图像裁剪(自定义裁剪图片大小)
    jquery实现点击文字后变成文本框且可修改
    mysql查看表注释和字段注释的方法
    php 获取中文字符串首字母
    Nginx.conf配置
    光盘作为yum源
    win7下安装mongodb
  • 原文地址:https://www.cnblogs.com/hongfei/p/2873361.html
Copyright © 2011-2022 走看看