設計模式之三:迭代器模式(IteratorPattern)

來源:互聯網
上載者:User

迭代器(Iterator)模式,又叫遊標(Cursor)模式。其定義為:提供一種方法訪問一個容器物件中各個元素,而又不需暴露該對象的內部細節。迭代器模式是和容器相關的,對容器物件的訪問設計到遍曆演算法。

迭代器模式由以下角色群組成:

  1. 迭代器角色(Iterator):迭代器角色負責定義訪問和遍曆元素的介面。
  2. 具體迭代器角色(Concrete Iterator):具體迭代器角色要實現迭代器介面,並記錄遍曆中的當前位置。
  3. 容器角色(Container):容器角色負責提供建立具體迭代器角色的介面。
  4. 具體容器角色(Concrete Container):具體容器角色實現建立具體迭代器角色的介面---這個迭代器角色與該容器的結構相關。

意圖:就是提供一種訪問集合對象的方法,而又無需暴露該對象的內部細節。

在.NET中的Iterator模式

   在.NET下實現的Iterator模式,對於聚集介面和迭代器介面已經存在了,其中IEnumerator扮演的就是迭代器的角色。它的代碼如下:

public interface IEnumerator

    {

        object Current

        {

            get;

        }

        void Reset();

        bool MoveNext();

    }

IEnumerable則扮演的就是抽象聚集的角色,只有一個GetEnumertor()方法。如果集合對象需要具備迭代遍曆的功能,就必須實現該介面。

public interface IEnumerable

    {

        IEnumerator GetEnumerator();

    }

下面看一個在網上http://www.theserverside.net/看到的.NET1.1下的迭代器例子,我稍微做了修改,Person類是一個可枚舉的類。PersonsEnumerator類是一個列舉程式類

public class Persons : IEnumerable

    {

        public string[] m_Names;

        public Persons(string[] names)

        {

            m_Names = new string[names.Length];

            names.CopyTo(m_Names, 0);

        }

        private string this[int index]

        {

            get

            {

                return m_Names[index];

            }

            set

            {

                m_Names[index] = value;

            }

        }

        public IEnumerator GetEnumerator()

        {

            return new PersonsEnumerator(this);

        }

    }

    public class PersonsEnumerator : IEnumerator

    {

        private int index = -1;

        private Persons p;

        public PersonsEnumerator(Persons p)

        {

            this.p = p;

        }

        public bool MoveNext()

        {

            if (index < p.m_Names.Length)

            {

                return true;

            }

            return false;

        }

        public void Reset()

        {

            index = -1;

        }

        public object Current

        {

            get

            {

                return p.m_Names[index];

            }

        }

    }

在.NET2.0及以後的版本,由於有了yield return關鍵字,實現起來就更簡單了:

public class Persons : IEnumerable

    {

        private string[] m_names;

        public Persons(string[] names)

        {

            m_names = new string[names.Length];

            names.CopyTo(m_names,0);

        }

        public IEnumerator GetEnumerator()

        {

            foreach(string name in m_names)

            {

                yield return name;

            }

        }

}

另外順便簡單介紹一下yield關鍵字:

關鍵字yield,在迭代器塊中用於向枚舉數對象提供值或發出迭代結束訊號。迭代器有兩個特殊語句:yield return <expression>;

                  Yield break;

迭代器塊

     迭代器塊是有一個或多個yield語句的程式碼程式庫。下面三種類型的代碼塊中任意一種都可以是迭代器塊:

     方法主體

     訪問器主體

     運算子主體

Yield語句只能出現在迭代器塊中,該塊可用作方法,運算子或訪問器的體。這類方法,運算子或訪問器的體受以下約束的控制:

  1. 不允許不安全塊
  2. 方法,運算子或訪問器的參數不能是ref或out
  3. Yield語句不能出現在匿名方法中
  4. Yield return語句不能出在catch塊中活含有一個或多個Catch子句的的try塊中。

Yield語句的跌代塊可以產生IEnumerator和IEnumerable兩種對象:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.