現在透過 VB 11 終於也可以有 C# 的方便性。使用 Iterator 與 Yield 我們也可以很方便實作出可舉列的型別或方法。我們先了解如何撰寫 Iterator 與 Yield 程式碼,然後在解釋整個 Iterator 與 Yield 的運作流程。
Module Module1 Sub Main() Dim number As Integer = 0 For Each number In SomeNumbers() Console.Write(number & " ") Next Console.ReadLine() ' 輸出:3 5 8 End Sub ''' <summary> ''' Iterator 函式 ''' </summary> Private Iterator Function SomeNumbers() As IEnumerable ' 使用多個 yield 關鍵字 Yield 3 Yield 5 Yield 8 End Function End Module
我們來看 SomeNumbers():
- 在 Function 之前,必須加上 Iterator 關鍵字
- 回傳值使用 Yield 關鍵字,而非 Return
- C# 使用 yield break 陳述式來結束 Iterator,VB 11 使用 Exit Function 或 Return 來結束
- C# 使用 yield return,VB 11 直接使用 Yield
- Iterator 的回傳型別只能是 IEnumerable、IEnumerable(Of T)、IEnumerator、IEnumrator(Of T) 四種。
我們來看在泛型裡的使用。
Module Module1 Sub Main() Dim number As Integer = 0 For Each number In EvenSequence(3, 19) Console.Write(number & " ") Next Console.ReadLine() ' 輸出:4 6 8 10 12 14 16 18 End Sub ''' <summary> ''' Iterator 在泛型的使用 ''' </summary> ''' <param name="firstNumber">開始數值</param> ''' <param name="lastNumber">結束數值</param> ''' <returns>偶數值</returns> Private Iterator Function EvenSequence(firstNumber As Integer, lastNumber As Integer) As IEnumerable(Of Integer) ' 回傳偶數 For number As Integer = firstNumber To lastNumber If number Mod 2 = 0 Then Yield number End If Next End Function End Module
在泛型裡使用 Iterator 沒有太大難處,與一般在 Function 裡使用一樣。如心得(1),本來 Yield number 那裡應該還再去實作一個類別,類別裡還要實作 IEnumerator介面,現在都省下來了。
我們再來看在類別裡的使用,這個例子比較像心得(1)範例與 Iterator 的結合:
Module Module1 Sub Main() Dim days As New DaysOfTheWeek() For Each day As String In days Console.Write(day & " ") Next Console.ReadLine() ' 輸出:Sun-星期日 ...略... End Sub End Module ''' <summary> ''' 在實作 IEnumerable.GetEnumerator 方法中使用 Iterator ''' </summary> Class DaysOfTheWeek Implements IEnumerable Public days() As String = {"Sun-星期日", "Mon-星期一", "Tue-星期二", "Wed-星期三", "Thr-星期四", "Fri-星期五", "Sat-星期六"} Iterator Function GetEnumerator() As IEnumerator Implements _ IEnumerable.GetEnumerator For i As Integer = 0 To days.Length - 1 Yield days(i) Next End Function End Class
我們在一個實作 IEnumerable介面的類別裡直接使用 Iterator 來簡化工作,心得(1)相比,我們減少實作整個 IEnumerator介面,帶來很大的方便性。
沒有留言:
張貼留言
感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。