天天看點

枚舉器和疊代器以及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];
            }
        }
    }
}