1. 程式人生 > >C#2.0 叠代器

C#2.0 叠代器

2.0 blog .com 運行 技術分享 color urn 做了 繼承

叠代器

叠代器模式是和為模式的一種範例,我們訪問數據序列中所有的元素,不用關心序列是什麽類型。從數據管道中數據經過一系列不同的轉換或過濾後從管道的另一端出來。

像數組、集合等已經內置了叠代器,我們可以直接進行foreach,而我們自定義的類型,自然是無法進行這個操作的,對於自定義的類型實現叠代器模式通過IEnumerableIEnumerator接口(或泛型接口)進行實現。在C#1.0中我們自定義類型實現叠代器是非常繁瑣的

自定義叠代器

想要對IterationSample進行foreach,首先繼承IEnumerable接口,會有一個GetEnumerator的方法需要去實現,這時創建另一個類實現

IEnumerator接口,實現MoveNext方法與Current屬性,我們需要進行位置的處理

技術分享

技術分享

這時就可以使用foreach這個"語法糖"進行遍歷了,為什麽說是語法糖呢, 因為這只是微軟進行的一個封裝處理,編譯成IL過後還是會看到調用了GetEnumerator、MoveNext以及Current

技術分享

技術分享

這裏在C#2.0中變的簡單了,這時使用yield return就可以代替整個IterationSampleIterator這個類。

技術分享

Yield return會告訴編譯器這不是一個普通方法,而是實現叠代器塊的方法。

這時可能會有疑問,都

yield return了是不是代表方法結束了,並不是這樣的,yield return 不代表方法執行結束 ,而是會在這裏暫時退出。Yield return內部會為我們生成一個狀態機,去維護MoveNext方法與Current屬性

這時也許想要看看IL會生成什麽樣的代碼呢,

可以看到有state(狀態)current(當前屬性)index(索引),用來記錄塊中位置以及局部變量的值 ,其實看起來和IterationSampleIterator類似,只不過幫我們去做了這個事

技術分享

可能會對暫時退出產生疑問

下面寫一個這樣的例子幫助理解,在yield return前與後都有相應的輸入,

for循環三次,在方法最後打印方法結束

技術分享

下面進行調用

技術分享

可以看到以下輸入,可以看到第一次執行MoveNext方法才會運行CreateEnumerable方法,也就是foreach是懶惰的,可以看到yield return方法就暫時退出了,只輸出了yield return 前,下一次movenext會從上次的位置繼續執行輸出yield return後,循環結束後才會輸出方法結束

技術分享

除了yield return,還有yield break,這才是真正的直接退出相當與普通方法的return

使用自定義叠代器,可以簡化對類型的遍歷,有時我們需要讀取文件中的第每一行,這樣的代碼經常會用到 。實現叠代器模型可以更加簡化代碼。

C#2.0 叠代器