VB.NET For Each 迴圈 (For Each Loop) 筆記 (基礎篇)
在 VB.NET 中,For Each 迴圈可以想成一個「智慧型自動導覽員」。它就像博物館裡專業的導覽員,能夠按照固定的路線,逐一帶領遊客參觀每一件展品,不會遺漏任何一個,也不會重複參觀。與傳統的 For 迴圈需要手動管理索引值不同,For Each 迴圈會自動處理遍歷的細節,讓程式設計師專注於處理每個元素的邏輯,而不用擔心計數器、邊界檢查等繁瑣事務。這種設計體現了現代程式語言中迭代器模式 (Iterator Pattern)一種設計模式,提供了一種方法來順序訪問聚合物件中的各個元素,而不需要暴露該物件的內部表示。它讓遍歷過程更加簡潔和安全,避免了直接操作索引可能造成的錯誤。的優雅實現。
認識 For Each 迴圈
For Each 迴圈: For Each 迴圈的核心目的,是為了安全且優雅地遍歷集合型資料。它會自動從集合的第一個元素開始,依序訪問每一個元素,直到最後一個元素處理完畢後自動結束。整個過程中,程式設計師不需要管理任何索引值或計數器,只需要專注於處理每個元素的業務邏輯即可。
- 自動遍歷: For Each 會「自動管理」遍歷過程,從第一個元素到最後一個元素,無需手動控制索引。
- 安全性高: 不會發生「索引超出範圍」的錯誤,因為迴圈邊界由系統自動控制。
- 程式碼簡潔: 語法簡單直觀,「可讀性極佳」,降低了出錯的可能性。
For Each 的使用方式
根據資料類型的不同,For Each 迴圈可以處理各種集合型資料結構,從最基本的陣列到複雜的泛型集合,以下是三種核心的應用場景整理。
功能一:遍歷陣列 (Array Traversal)
這是 For Each 迴圈最基本也是最常見的用法。就像導覽員帶領遊客參觀一排展示櫃,從第一個櫃子開始,逐一介紹每個櫃子裡的展品,直到最後一個櫃子參觀完畢。陣列中的每個元素都會被依序取出,程式設計師可以對每個元素進行相同的處理操作。
基本語法
For Each 元素變數 As 資料型別 In 陣列名稱
' 處理每個元素的程式碼
Next
元件清單
- Label1: 用於顯示遍歷後的結果。
- Button1: 觸發陣列遍歷的按鈕。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim fruits() As String = {"蘋果", "香蕉", "橘子", "葡萄", "草莓"}
Dim result As String = "水果清單:" & vbCrLf
For Each fruit As String In fruits
result &= "- " & fruit & vbCrLf
Next
Label1.Text = result
End Sub
End Class
限制與迴避方法
限制:使用 For Each 遍歷陣列時,無法直接修改陣列元素的值,因為迴圈變數是元素的複本,不是元素本身的參考。
迴避方法:如果需要修改陣列元素,應該使用傳統的 For 迴圈搭配索引,或者使用 For Each 搭配物件參考型別(如類別實例)。
功能二:遍歷泛型集合 (Generic Collections)
現代 .NET 程式設計中,泛型集合(如 List(Of T)、Dictionary(Of TKey, TValue))比傳統陣列更加靈活和功能強大。For Each 迴圈同樣能夠優雅地處理這些集合。這就像導覽員不僅能夠帶領遊客參觀固定的展示櫃,還能夠靈活地引導大家參觀各種不同類型的展覽區域,無論是畫廊、雕塑區還是互動體驗區。
基本語法
For Each 元素變數 As 資料型別 In 集合變數
' 處理每個元素的程式碼
Next
元件清單
- Label1: 用於顯示學生資訊清單。
- Button1: 觸發集合遍歷的按鈕。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim students As New List(Of String)
students.Add("張小明")
students.Add("李小華")
students.Add("王小美")
students.Add("陳小強")
Dim result As String = "班級學生名單:" & vbCrLf
Dim studentNumber As Integer = 1
For Each studentName As String In students
result &= studentNumber.ToString("00") & ". " & studentName & vbCrLf
studentNumber += 1
Next
Label1.Text = result
End Sub
End Class
限制與迴避方法
限制:在使用 For Each 遍歷集合時,不能在迴圈執行過程中修改集合的結構(如新增或刪除元素),這會導致執行時期異常。
迴避方法:若需要在遍歷過程中修改集合,可以先將要處理的元素複製到另一個集合,或者使用傳統的 For 迴圈倒序遍歷。
For Each 遍歷流程圖
功能三:處理複雜物件集合 (Object Collections)
在實際開發中,我們經常需要處理包含自訂物件的集合,每個物件都有多個屬性和方法。For Each 迴圈在這種情況下展現出真正的威力,它能夠讓我們輕鬆地存取每個物件的屬性,進行複雜的業務邏輯處理。這就像博物館導覽員不僅知道每件展品的位置,還能詳細介紹每件展品的歷史背景、藝術價值和技術特色。
基本語法
For Each 物件變數 As 類別名稱 In 物件集合
Dim value = 物件變數.屬性名稱
Next
元件清單
- Label1: 用於顯示產品統計資訊。
- Button1: 觸發產品資料處理的按鈕。
範例程式碼
Public Class Product
Public Property Name As String
Public Property Price As Decimal
Public Property Category As String
Public Sub New(name As String, price As Decimal, category As String)
Me.Name = name
Me.Price = price
Me.Category = category
End Sub
End Class
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim products As New List(Of Product)
products.Add(New Product("筆記型電腦", 35000, "電子產品"))
products.Add(New Product("無線滑鼠", 800, "電子產品"))
products.Add(New Product("咖啡杯", 150, "生活用品"))
products.Add(New Product("原子筆", 25, "文具用品"))
Dim totalValue As Decimal = 0
Dim expensiveProducts As Integer = 0
Dim result As String = "產品清單分析:" & vbCrLf & vbCrLf
For Each product As Product In products
totalValue += product.Price
If product.Price > 1000 Then
expensiveProducts += 1
End If
result &= "【" & product.Name & "】 $" & product.Price.ToString("N0") & " (" & product.Category & ")" & vbCrLf
Next
result &= vbCrLf & "統計資訊:" & vbCrLf
result &= "總商品數量:" & products.Count.ToString() & " 件" & vbCrLf
result &= "總價值:$" & totalValue.ToString("N0") & vbCrLf
result &= "高價商品:" & expensiveProducts.ToString() & " 件"
Label1.Text = result
End Sub
End Class
限制與迴避方法
限制:For Each 迴圈中的物件變數是唯讀的參考,雖然可以修改物件的屬性,但不能將物件變數指向其他物件實例。
迴避方法:這通常不是問題,因為我們很少需要在迴圈中重新指派物件參考。如果確實需要,可以使用傳統的 For 迴圈搭配索引來存取集合元素。
For Each vs For 迴圈比較
| 比較項目 | For Each 迴圈 | 傳統 For 迴圈 |
|---|---|---|
| 語法複雜度 | 語法簡潔,無需管理索引變數。 | 需要手動宣告和管理計數器變數。 |
| 安全性 | 自動邊界檢查,不會發生索引超出範圍錯誤。 | 需要手動控制邊界,容易出現索引錯誤。 |
| 效能表現 | 對於大多數集合類型,效能與 For 迴圈相當或更佳。 | 在某些特定情況下可能略快,但差異通常微不足道。 |
| 靈活性 | 只能順序遍歷,無法跳躍或倒序。 | 可以任意控制遍歷順序和步進值。 |
| 索引存取 | 無法直接取得當前元素的索引位置。 | 可以同時取得索引和元素值。 |
進階 For Each 技巧
除了基本應用,For Each 還提供了一些進階語法和技巧,讓程式碼的撰寫更加優雅和高效。
技巧一:使用 Exit For 提前離開迴圈Exit For 是 VB.NET 中用來提前終止迴圈執行的關鍵字。當程式在迴圈執行過程中遇到特定條件時,可以使用 Exit For 立即跳出迴圈,繼續執行迴圈後面的程式碼。
有時候我們不需要處理集合中的所有元素,當找到符合條件的元素時就可以停止搜尋。這時可以使用 Exit For 語句提前離開迴圈,提升程式執行效率。這就像導覽員在尋找特定展品時,一旦找到目標就不需要繼續參觀其他展品。
實際應用場景
常用於搜尋特定元素、驗證條件或在大型集合中進行效能最佳化,避免不必要的遍歷操作。
元件清單
- Label1: 用於顯示搜尋結果。
- Button1: 觸發搜尋操作的按鈕。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim orderNumbers() As String = {"ORD001", "ORD002", "ORD003", "ORD004", "ORD005"}
Dim targetOrder As String = "ORD003"
Dim found As Boolean = False
Dim searchCount As Integer = 0
For Each orderNumber As String In orderNumbers
searchCount += 1
If orderNumber = targetOrder Then
found = True
Exit For
End If
Next
If found Then
Label1.Text = "找到訂單 " & targetOrder & "!" & vbCrLf & "搜尋了 " & searchCount.ToString() & " 個項目"
Else
Label1.Text = "未找到指定的訂單編號"
End If
End Sub
End Class
技巧二:使用 Continue For 跳過當前迭代Continue For 是 VB.NET 中用來跳過當前迴圈迭代的關鍵字。當程式在迴圈執行過程中遇到特定條件時,可以使用 Continue For 跳過當前元素的處理,直接進入下一個元素的迭代。
有時候我們需要有條件地處理集合中的元素,對於不符合條件的元素可以跳過處理,繼續下一個元素。Continue For 語句讓我們能夠優雅地實現這種選擇性處理邏輯。這就像導覽員在參觀過程中,遇到正在維修的展品時會跳過不介紹,直接前往下一個展品。
實際應用場景
適用於資料篩選、條件性處理、異常資料跳過等情境,讓程式邏輯更加清晰和高效。
元件清單
- Label1: 用於顯示篩選後的成績統計。
- Button1: 觸發成績處理的按鈕。
範例程式碼
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim scores() As Integer = {85, -1, 92, 78, -1, 88, 95, 0, 76, -1}
Dim validScoreCount As Integer = 0
Dim totalValidScore As Integer = 0
Dim result As String = "有效成績分析:" & vbCrLf & vbCrLf
For Each score As Integer In scores
If score <= 0 Then
Continue For
End If
validScoreCount += 1
totalValidScore += score
result &= "第" & validScoreCount.ToString() & "個有效成績:" & score.ToString() & "分" & vbCrLf
Next
If validScoreCount > 0 Then
Dim averageScore As Double = totalValidScore / validScoreCount
result &= vbCrLf & "統計結果:" & vbCrLf
result &= "有效成績數量:" & validScoreCount.ToString() & vbCrLf
result &= "平均成績:" & averageScore.ToString("F1") & "分"
Else
result &= vbCrLf & "沒有找到有效的成績資料"
End If
Label1.Text = result
End Sub
End Class
總結
For Each 迴圈是 VB.NET 中處理集合資料的首選工具,它提供了簡潔、安全且高效的遍歷方式。正確理解和使用 For Each 迴圈可以讓程式碼更加優雅和易於維護。
記住以下關鍵要點:
- 優先使用 For Each 而非傳統 For 迴圈
- 注意 For Each 無法修改集合結構的限制
- 善用 Exit For 和 Continue For 提升效率
- 在需要索引時考慮使用傳統 For 迴圈
- For Each 適用於所有實現 IEnumerable 介面的集合
最佳實務建議
優先選擇 For Each:除非你需要索引值、倒序遍歷或自訂步進值,否則都應該優先使用 For Each 迴圈。它不僅語法更簡潔,也更不容易出錯,是現代程式設計中推薦的迭代方式。