CSharpThinking 迭代器(三)

2022-01-17 13:09:02 字數 3456 閱讀 2137

迭代器是行為模式的一種範例,而行為模式是一種簡化物件之間通訊的設計模式。它允許你乙個資料項列表中的所有元素,而無需關心序列是什麼型別---陣列,列表,鍊錶等。它能

非常有效的構建出乙個資料管道,資料項由此進入管道,並以不同的變換方式來遍歷這些資料,或者在訪問到末端之前進行一些過濾操作,事實上,這也是linq核心模式的一種。

一,迭代器重要概念1.1 如果乙個類實現了ienumerable介面,則它就可以被迭代器訪問,稱為可迭代,呼叫getenumerator返回ienumerator,這就是迭代器本身,相當於資料庫的游標。

1.2 c#1中不能試用yield return 。而c#2中實現了 yield return模式,大大簡化構建乙個迭代器。

二,迭代器工作流程

2.1 手動實現yield return,工作流程展示。

1

static

readonly

string padding = new

string('

', 30);2

3static ienumerablecreateenumerable()

4 start of createnumerable()

",padding);67

for (int i = 0; i < 3; i++)

8 about to yield

", padding, i);

10yield

return

i;11 console.writeline("

after yield return

",padding);12}

13 console.writeline("

yielding final value

",padding);

14yield

return -1

;15 console.writeline("

end of createnumerable()

", padding);16}

1718

public

void

testmain() 19"

,result);

29if (!result)

3033 console.writeline("

fetching current...");

34 console.writeline("

...current result =

",iterator.current);35}

36 }

結果:

以上結果說明問題:

1. 在第一次呼叫movenext之前,createenumerable中的**不會被呼叫。

2. 所有工作都在呼叫movenext的時候就完成了,獲取current值不會執行任何**;

3. 在yield return的位置,**就停止執行,在下一次呼叫movenext的時候又繼續執行;

4. 在乙個方法中的不同地方可以書寫多個yield return語句;

5. **不會在最後的yield return出結束---相反,而是通過返回false的movenext呼叫來借宿方法的執行。

2.2 與try/finally一起使用的yield break

2.2.1 使用yield break不會像yield return一樣,看上去退出了迴圈。

2.2.2 如果使用foreach迴圈呼叫迭代器成員,則最後會隱式執行dispose(),導致最終會執行finally,**如下:

1

static ienumerablecountwithtimelimit(datetime dt)211

}12finally

1316}17

18void

testmain2()19

", i);

24if (i > 3)25

29 thread.sleep(300

);30}31

}3233/*

result:

34* received 1

35* received 2

36* received 3

37* received 4

38* returning...

39* stropping...

40*

*/

三, 迭代器例子

3.1 c#2 例子

1

///2

///c#2.0 迭代器應用

3///

4///

5///

封裝內部方法

6///

7///

8///

9static ienumerable readlines(funcprovider)

1018}19

}20///21

///過載readlines

22///

23///

24///

25///

26static ienumerable readlines(string

filename, encoding encoding)

27);29}

30///

31///

測試**

32///

33void

testmain3()

3439 }

3.2 由於迭代器的延遲特性,如果想在呼叫之前檢查**,如下所示:(上文中的movenext之前是不會執行任何**的)

1

///2

///外部公開方法:先檢查,然後呼叫私有方法執行(延遲執行)方法。

3///

4///

5///

6///

7///

8public

static ienumerablewhere

(ienumerablesource, predicatepredicate)914

15private

static ienumerablewhereimpl(ienumerablesource, predicatepredicate)

1622 }

3.3 ccr實現偽同步**:核心思想呼叫迭代器中的yield return

這種用法的核心思想是狀態機:非同步開發中兩個複雜的問題就是處理狀態和在感興趣的事情發生之前進行有效的暫停。迭代器塊使這兩個問題得以完美的解決。

CSharpThinking 擴充套件方法(四)

本章主要描述擴充套件方法的應用及相關原理。一,演變 1.1 擴充套件方法特徵 1 必須在乙個靜態方法中。2 至少有乙個引數。3 第乙個引數必須附加this關鍵字作為字首。4 第乙個引數不能有其他任何修飾符 如 out,ref 5 第乙個引數的型別不能是指標。6 如果擴充套件方法名稱與型別的方法一樣 ...

迭帶加深搜尋

poj 2248 addition chains 迭代加深 by admin 瀏覽 56 題意 加法鏈的 定義是第乙個元素是 1,最後乙個是 n,所有元素從小到大排列,並且除了 1之外任意乙個元素都是前面兩個元素的和 那兩個元素可相同 給定 n,求元素最少的加法鏈 思路 做這個題,特意學了下迭代加深...

JavaSe筆記Collection之迭代器

作用 提供了遍歷容器的統一介面 iterator介面 一共有三個方法 迭代器原理 通過容器物件的iterator 方法,獲得容器物件的迭代器物件 iterator it arraylist.iterator 迭代器物件中有乙個游標cursor,游標初始時預設指向要遍歷的第乙個元素前面 it.hasn...