天天看点

枚举器和迭代器以及unity协程

从这两个接口的用词选择上,也可以看出其不同:      

a) IEnumerable是一个声明式的接口,声明实现该接口的类是可枚举。

b) IEnumerator是一个实现式的接口,IEnumerator对象说明如何实现枚举器。

Foreach语句隐式调用集合的无参GetEnumerator方法(不论集合是否有实现IEnumerable接口,但只要有无参GetEnumerator方法并返回IEnumerator就可遍历)。      
集合类为什么不直接实现IEnumerable和IEnumerator接口?      

这样是为了提高并发性。Eg:一个遍历机制只有一个Current,一旦并发就会出错。然而“将遍历机制与集合分离开来”如果要实现同时遍历同一个集合,只需由集合IEnumerable.GetEnumerator() 返回一个新的包含遍历机制(IEnumerator)的类实例即可。

枚举器和迭代器以及unity协程

01:foreach在数组集合的遍历时会被经常用到,例如

枚举器和迭代器以及unity协程

使用foreach做遍历确实很方便,然而并不是每一种类型都能使用foreach进行遍历操作,只有实现了IEnumerable接口的类(也叫做可枚举类型)才能进行foreach的遍历操作,集合和数组已经实现了这个接口,所以能进行foreach的遍历操作

02:

foreach是对集合进行遍历,而集合都继承Array类
foreach结构设计用来和可枚举类型一起使用,只要给它的遍历对象是可枚举类型
只有实现了IEnumerable接口的类(也叫做可枚举类型)才能进行foreach的遍历操作,集合和数组已经实现了这个接口,所以能进行foreach的遍历操作
集合继承IEnumerable这个接口,而IEnumerable的 IEnumerator GetEnumerator()方法 可以获得一个可用于循环访问集合的 对象


        List<string> list = new List<string>() { "252", "哈哈哈", "25256", "春天里的花朵" };
        Console.WriteLine(list.GetType().Name);

        IEnumerator listEnumerator = list.GetEnumerator();
        while (listEnumerator.MoveNext())
        {
            Console.WriteLine(listEnumerator.Current);
        }
        listEnumerator.Reset();      
namespace System.Collections
{
    //
    // 摘要:
    //     公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。 若要浏览此类型的.NET Framework 源代码,请参阅Reference Source。
    [ComVisible(true)]
    [Guid("496B0ABE-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerable
    {
        //
        // 摘要:
        //     返回循环访问集合的枚举数。
        //
        // 返回结果:
        //     一个可用于循环访问集合的 System.Collections.IEnumerator 对象。
        [DispId(-4)]
        IEnumerator GetEnumerator();
    }
}      
//枚举器内部的方法
namespace System.Collections
{
    //
    // 摘要:
    //     支持对非泛型集合的简单迭代。
    [ComVisible(true)]
    [Guid("496B0ABF-CDEE-11d3-88E8-00902754C43A")]
    public interface IEnumerator
    {
        //
        // 摘要:
        //     获取集合中位于枚举数当前位置的元素。
        //
        // 返回结果:
        //     集合中位于枚举数当前位置的元素。
        object Current { get; }

        //
        // 摘要:
        //     将枚举数推进到集合的下一个元素。
        //
        // 返回结果:
        //     如果枚举数已成功地推进到下一个元素,则为 true;如果枚举数传递到集合的末尾,则为 false。
        //
        // 异常:
        //   T:System.InvalidOperationException:
        //     创建枚举器后,已修改该集合。
        bool MoveNext();
        //
        // 摘要:
        //     将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
        //
        // 异常:
        //   T:System.InvalidOperationException:
        //     创建枚举器后,已修改该集合。
        void Reset();
    }
}      
using System;
using  System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 枚举器和迭代器
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass=new MyClass();
            while (myClass.MoveNext())
            {
                Console.WriteLine(myClass.Current);
            }
            myClass.Reset();

            IEnumerator iEnumerator=myClass.GetEnumerator();
            while (iEnumerator.MoveNext())
            {
                Console.WriteLine(iEnumerator.Current);
            }
            myClass.Reset();

            foreach (string  item in myClass.Names)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }


    //可枚举的类型可以被枚举遍历
    class MyClass: IEnumerator,IEnumerable
    {
        public string[] Names { get; set;}


        public MyClass()
        {
            Names = new string[] {"22", "就", "333"};
        }
        private int postion = -1;

        //枚举器的方法
        public object Current
        {
            get
            {
                if (postion>=0&&postion<Names.Length)
                {
                    return Names[postion];
                }

                return null;
            }
        }
        public bool MoveNext()
        {
            if (postion<Names.Length)
            {
                postion++;
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Reset()
        {
            postion = -1;
        }

        //获取枚举器
        public IEnumerator GetEnumerator()
        {
            return new MyClass();
        }
    }
   
}      
namespace 迭代器
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass=new MyClass();
            foreach (var item in myClass)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }

    public class MyClass : IEnumerable
    {

        public string[] Names { get; set; }
        public MyClass()
        {
            Names = new string[] { "22", "就", "333" };
        }
        public IEnumerator GetEnumerator()
        {
            for (int i = 0; i < Names.Length; i++)
            {
                yield return Names[i];
            }
        }
    }
}