歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 探討關於C#中Foreach的本質

探討關於C#中Foreach的本質

日期:2017/3/1 9:16:39   编辑:Linux編程

一.為什麼數組和集合可以使用foreach遍歷

01. 因為數組和集合都實現了IEnumerable接口,該接口中只有一個方法,GetEnumerator()

02.數組類型是從抽象基類型 Array 派生的引用類型。由於此類型實現了 IEnumerable ,因此可以對 C# 中的所有數組使用 foreach 迭代。(摘自MSDN)

二.探討針對於List集合微軟的是怎麼實現這個IEnumerable接口的

該接口的方法

public interface IEnumerable

    {

        // 摘要:

        //     返回一個循環訪問集合的枚舉數。

        //

        // 返回結果:

        //     一個可用於循環訪問集合的 System.Collections.IEnumerator 對象。

        [DispId(-4)]

        IEnumerator GetEnumerator();

} 

對於GetEnumerator這個方法他的返回值時又是一個接口類型。所以在這裡還要看IEnumerator的接口內容。

public interface IEnumerator

    {

        // 摘要:

        //     獲取集合中的當前元素。

        //

        // 返回結果:

        //     集合中的當前元素。

        object Current { get; }

 

        // 摘要:

        //     將枚舉數推進到集合的下一個元素。

        //

        // 返回結果:

        //     如果枚舉數成功地推進到下一個元素,則為 true;如果枚舉數越過集合的結尾,則為 false。

        //

        // 異常:

        //   System.InvalidOperationException:

        //     在創建了枚舉數後集合被修改了。

        bool MoveNext();

        //

        // 摘要:

        //     將枚舉數設置為其初始位置,該位置位於集合中第一個元素之前。

        //

        // 異常:

        //   System.InvalidOperationException:

        //     在創建了枚舉數後集合被修改了。

        void Reset();

    }

所以不難發現微軟是通過這種方法的實現遍歷迭代變量的

三.通過C#代碼實現自定義類型的集合遍歷

首先該類必須實現IEnumerable接口

 //01自定義類型:實現IEnumerable接口,證明這個類型保存的數據能被foreach遍歷

    //IEnumberable這個接口,在微軟底層有一個方法GetEnumerator()返回值類型是IEnumerator接口

    public class MyList:IEnumerable

    {

        //02定義一個集合

        ArrayList list=new ArrayList();

        //03實現IEnumberable的方法

        public IEnumerator GetEnumerator()

        {

           return new MyIEnumerator(list);

        }

 

        public void Add(Object oj)

        {

            list.Add(oj);

        }

}
//IEnumerator:支持對非泛型集合的簡單迭代

    public class MyIEnumerator:IEnumerator

    {

        //01定義一個List集合

        ArrayList list=new ArrayList();

        //02無參構造

        public MyIEnumerator(ArrayList list)

        {

            //跟當前類的集合賦值

            this.list = list;

        }

 

        public object Current

        {

            get { return list[index]; }

        }

        //04默認將集合的索引指向前一個

        private int index = -1;

        //05實現接口的Movenext方法

        public bool MoveNext()

        {

            bool happy = false;//默認為沒有數據

            if (list.Count - 1 > index)

            {

                //證明集合中有數據讓索引加1

                index++;

                //改變bool值為true

                happy = true;

            }

            return happy;

        }

 

        public void Reset()

        {

            index = -1;

 

        }

    }
 MyList list=new MyList();

     list.Add("小王");

     list.Add("小李");

     foreach (string item in list)

     {

         Console.WriteLine(item);

      }

    Console.ReadKey();

Copyright © Linux教程網 All Rights Reserved