C# 中的 Iterator(选代器)
Iterator 是其中一種經常使用的設計模式。當你想列舉一個集合 而不想暴露它的細節時。Iterator 是合適的實現方法。 如大家曾編寫過Iterator 模式的話, 它的寫法 和以下代碼會有點兒相同。
以下是一個用來保存string 的Iterator
編寫一個正確的iterator 是非常沈悶的事。 概然 iterator 是那麼常用, 那應該把它寫在較底層的library 中。讓代碼能夠重用。才是上上之策。 考慮到這點, 其實C# 的團隊早已把Iterator 模式實現在C# 中 。 所以大家其實不需要自己編寫Iterator。 Iterator 的代碼早已定義在一個名為IEnumerator 的Interface 中。但我們要如何使用已定義好的代碼呢?
先看看List 類別的代碼。
從List 的代碼中看到, List 實現了IEnumerable 這個Interface。 在IEnumerable 中 定義了一個名為GetEnumerator 的方法。 該方法的返回類型是IEnumerator。
其實List 這個類別之所以能夠使用foreach來列舉,實際上就是因為它實現了IEnumerable 這個介面。 在實際編釋中,foreach 實際上是呼叫GetEnumerator 。在以下的例子中, 我實現了一個MessageBox 集合來保存類別為Message 的物件
例子
Message的定義
MesaageBox的定義
這時候, MessageBox 還未實現 IEnumerable Interface。 如在這時使用foreach 來列舉MessageBox的話 , 會出現編釋錯誤。
但當MesaageBox實現了IEnumerable 的話, 編譯錯誤就會消失。
最後在GetEnumerator 中加入以下代碼
便能夠使用foreach 列舉集合中的元素了。
當中yield 的意思是可以理解成先return 再執行的意思。所以執行結果會是在 顯示Before Yield 後顯示 "xxx give xxx a message.Content is xxx. It has not sent yet" 最後才顯示 After Yield。
而不是列舉完整個集合後,最後才顯示"xxx give xxx a message. Content is xxx. It has not sent yet" 。
源代碼在 https://github.com/Isaac234517/C-_IteratorEample
總結
在自定義的集合類別中實現IEnumerable 能使代碼變得更為整結、簡短和很輕易就獲得Iterator 模式的好處。大大降低了開發時間。所以當大家下次遇到要實現自定義集合的情況時,務必要自定義集合類別實現IEnumerable Interface了。源代碼在 https://github.com/Isaac234517/C-_IteratorEample
留言
張貼留言