Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Mengulangi sekelompok pernyataan untuk setiap elemen dalam koleksi.
Sintaksis
For Each element [ As datatype ] In group
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ element ]
Bagian
| Istilah | Definisi |
|---|---|
element |
Diperlukan dalam pernyataan For Each. Opsional dalam Next pernyataan. Variabel. Digunakan untuk melakukan iterasi melalui elemen koleksi. |
datatype |
Opsional jika Option Infer aktif (default) atau element sudah dinyatakan; diperlukan jika Option Infer nonaktif dan element belum dideklarasikan. Jenis data dari element. |
group |
Dibutuhkan. Variabel dengan jenis yang merupakan jenis koleksi atau Objek. Mengacu pada koleksi yang statements akan diulang. |
statements |
Fakultatif. Satu atau beberapa pernyataan antara For Each dan Next yang berjalan pada setiap item di group. |
Continue For |
Fakultatif. Mentransfer kontrol ke awal perulangan For Each . |
Exit For |
Fakultatif. Memindahkan kendali keluar dari perulangan For Each . |
Next |
Dibutuhkan. Mengakhiri definisi dari perulangan For Each. |
Contoh Sederhana
For EachGunakan perulangan ...Next saat Anda ingin mengulang sekumpulan pernyataan untuk setiap elemen koleksi atau array.
Tip
A Untuk... Pernyataan Berikutnya berfungsi dengan baik ketika Anda dapat mengaitkan setiap perulangan perulangan dengan variabel kontrol dan menentukan nilai awal dan akhir variabel tersebut. Namun, ketika Anda berhadapan dengan koleksi, konsep nilai awal dan akhir tidak bermakna, dan Anda tidak selalu tahu berapa banyak elemen yang dimiliki koleksi. Dalam kasus seperti ini, perulangan For EachseringkaliNext merupakan pilihan yang lebih baik.
Dalam contoh berikut, For Each...
Next pernyataan berulang melalui semua elemen kumpulan Daftar.
' Create a list of strings by using a
' collection initializer.
Dim lst As New List(Of String) _
From {"abc", "def", "ghi"}
' Iterate through the list.
For Each item As String In lst
Debug.Write(item & " ")
Next
Debug.WriteLine("")
'Output: abc def ghi
Untuk contoh selengkapnya, lihat Koleksi dan Array.
Perulangan Berlapis
Anda dapat menyarangkan For Each perulangan dengan menempatkan satu perulangan di dalam perulangan lainnya.
Contoh berikut menunjukkan berlapis For Each...
Next Struktur.
' Create lists of numbers and letters
' by using array initializers.
Dim numbers() As Integer = {1, 4, 7}
Dim letters() As String = {"a", "b", "c"}
' Iterate through the list by using nested loops.
For Each number As Integer In numbers
For Each letter As String In letters
Debug.Write(number.ToString & letter & " ")
Next
Next
Debug.WriteLine("")
'Output: 1a 1b 1c 4a 4b 4c 7a 7b 7c
Saat Anda menyarangkan perulangan, setiap perulangan harus memiliki variabel unik element .
Anda juga dapat menumpuk berbagai jenis struktur kontrol satu sama lain. Untuk informasi selengkapnya, lihat Struktur Kontrol Tertumpuk.
Keluar Dari dan Lanjutkan Dari
Pernyataan Exit For menyebabkan eksekusi keluar dari For...
Next loop dan memindahkan kendali ke pernyataan yang mengikuti Next.
Pernyataan Continue For mentransfer kontrol segera ke iterasi berikutnya dalam perulangan. Untuk informasi selengkapnya, lihat Lanjutkan Pernyataan.
Contoh berikut menunjukkan cara menggunakan Continue For pernyataan dan Exit For .
Dim numberSeq() As Integer =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}
For Each number As Integer In numberSeq
' If number is between 5 and 8, continue
' with the next iteration.
If number >= 5 And number <= 8 Then
Continue For
End If
' Display the number.
Debug.Write(number.ToString & " ")
' If number is 10, exit the loop.
If number = 10 Then
Exit For
End If
Next
Debug.WriteLine("")
' Output: 1 2 3 4 9 10
Anda dapat menempatkan sejumlah Exit For pernyataan dalam perulangan For Each . Ketika digunakan dalam perulangan bertumpuk For Each , Exit For menyebabkan eksekusi keluar dari perulangan paling dalam dan mentransfer kontrol ke tingkat bersarang berikutnya yang lebih tinggi.
Exit Forsering digunakan setelah evaluasi beberapa kondisi, misalnya, dalam ...IfThen...Else struktur. Anda mungkin ingin menggunakan Exit For untuk kondisi berikut:
Melanjutkan iterasi tidak perlu atau tidak mungkin. Ini mungkin disebabkan oleh nilai yang salah atau permintaan penghentian.
Pengecualian tertangkap dalam
Try...Catch...Finally. Anda dapat menggunakanExit Fordi akhirFinallyblok.Ada perulangan tanpa akhir, yang merupakan perulangan yang dapat menjalankan sejumlah besar atau bahkan tak terbatas. Jika Anda mendeteksi kondisi seperti itu, Anda dapat menggunakan
Exit Foruntuk menghindari perulangan. Untuk informasi selengkapnya, lihat Pernyataan Do...Loop.
Iterator
Anda menggunakan iterator untuk melakukan iterasi kustom melalui koleksi. Iterator dapat berupa fungsi atau Get aksesor. Ini menggunakan Yield pernyataan untuk mengembalikan setiap elemen koleksi satu per satu.
Anda memanggil iterator dengan menggunakan For Each...Next pernyataan. Setiap iterasi dari perulangan For Each memanggil iterator.
Yield Ketika pernyataan tercapai di iterator, ekspresi dalam Yield pernyataan dikembalikan, dan lokasi saat ini dalam kode dipertahankan. Eksekusi dimulai ulang dari lokasi tersebut saat berikutnya iterator dipanggil.
Contoh berikut menggunakan fungsi iterator. Fungsi iterator memiliki Yield pernyataan yang ada di dalam For... Perulangan berikutnya . Dalam metode , ListEvenNumbers setiap iterasi For Each isi pernyataan membuat panggilan ke fungsi iterator, yang melanjutkan ke pernyataan berikutnya Yield .
Public Sub ListEvenNumbers()
For Each number As Integer In EvenSequence(5, 18)
Debug.Write(number & " ")
Next
Debug.WriteLine("")
' Output: 6 8 10 12 14 16 18
End Sub
Private Iterator Function EvenSequence(
ByVal firstNumber As Integer, ByVal lastNumber As Integer) _
As System.Collections.Generic.IEnumerable(Of Integer)
' Yield even numbers in the range.
For number = firstNumber To lastNumber
If number Mod 2 = 0 Then
Yield number
End If
Next
End Function
Untuk informasi selengkapnya, lihat Iterator, Pernyataan Hasil, dan Iterator.
Implementasi Teknis
Ketika ...For Each
Next pernyataan berjalan, Visual Basic mengevaluasi koleksi hanya satu kali, sebelum perulangan dimulai. Jika blok pernyataan Anda berubah element atau group, perubahan ini tidak memengaruhi perulangan perulangan.
Ketika semua elemen dalam koleksi telah secara berturut-turut ditetapkan ke element, For Each perulangan berhenti dan kontrol diteruskan ke pernyataan setelah Next pernyataan.
Jika Opsi Infer aktif (pengaturan defaultnya), pengkompilasi Visual Basic dapat menyimpulkan jenis elementdata . Jika tidak aktif dan element belum dinyatakan di luar perulangan, Anda harus menyatakannya dalam For Each pernyataan. Untuk mendeklarasikan jenis element data secara eksplisit, gunakan As klausa. Kecuali jenis data elemen didefinisikan di luar For Eachkonstruksi ...Next , cakupannya adalah isi perulangan. Perhatikan bahwa Anda tidak dapat mendeklarasikan element baik di luar maupun di dalam perulangan.
Anda dapat secara opsional menentukan element dalam Next pernyataan. Ini meningkatkan keterbacaan program Anda, terutama jika Anda memiliki perulangan berlapis For Each . Anda harus menentukan variabel yang sama dengan variabel yang muncul dalam pernyataan yang For Each sesuai.
Anda mungkin ingin menghindari perubahan nilai element di dalam perulangan. Melakukan ini dapat membuatnya lebih sulit untuk membaca dan men-debug kode Anda. Mengubah nilai group tidak memengaruhi koleksi atau elemennya, yang ditentukan ketika perulangan pertama kali dimasukkan.
Saat Anda menyarangkan perulangan, jika Next pernyataan tingkat berlapis luar ditemui sebelum Next tingkat dalam, pengkompilasi memberi sinyal kesalahan. Namun, pengkompilasi dapat mendeteksi kesalahan yang tumpang tindih ini hanya jika Anda menentukan element di setiap Next pernyataan.
Jika kode Anda tergantung pada melintas koleksi dalam urutan tertentu, For Eachperulangan ...Next bukanlah pilihan terbaik, kecuali Anda tahu karakteristik objek enumerator yang diekspos koleksi. Urutan traversal tidak ditentukan oleh Visual Basic, tetapi dengan MoveNext metode objek enumerator. Oleh karena itu, Anda mungkin tidak dapat memprediksi elemen koleksi mana yang pertama kali dikembalikan dalam element, atau yang merupakan elemen berikutnya yang dikembalikan setelah elemen tertentu. Anda mungkin mencapai hasil yang lebih andal menggunakan struktur perulangan yang berbeda, seperti For...Next atau Do...Loop.
Runtime harus dapat mengonversi elemen ke groupelement. Pernyataan [Option Strict] mengontrol apakah konversi yang melebar dan mempersempit diizinkan (Option Strict nonaktif, nilai defaultnya), atau apakah hanya melebarkan konversi yang diizinkan (Option Strict aktif). Untuk informasi selengkapnya, lihat Mempersempit konversi.
Jenis group data harus merupakan jenis referensi yang mengacu pada koleksi atau array yang dapat dijumlahkan. Paling umum ini berarti bahwa group mengacu pada objek yang mengimplementasikan IEnumerable antarmuka System.Collections namespace layanan atau IEnumerable<T> antarmuka System.Collections.Generic namespace layanan.
System.Collections.IEnumerable mendefinisikan GetEnumerator metode , yang mengembalikan objek enumerator untuk koleksi. Objek enumerator mengimplementasikan System.Collections.IEnumerator antarmuka System.Collections namespace layanan dan mengekspos Current properti dan Reset metode dan MoveNext . Visual Basic menggunakan ini untuk melintasi koleksi.
Konversi yang Menyempit
Ketika Option Strict diatur ke On, mempersempit konversi biasanya menyebabkan kesalahan kompilator. Namun, dalam pernyataan For Each , konversi dari elemen ke groupelement dievaluasi dan dilakukan pada waktu proses, dan kesalahan kompilator yang disebabkan oleh konversi yang mempersempit ditekan.
Dalam contoh berikut, penetapan m sebagai nilai awal untuk n tidak mengkompilasi kapan Option Strict aktif karena konversi ke Long adalah konversi yang Integer menyempit. Namun, dalam pernyataan, For Each tidak ada kesalahan kompilator yang dilaporkan, meskipun penugasan untuk number memerlukan konversi yang sama dari Long ke Integer.
For Each Dalam pernyataan yang berisi angka besar, kesalahan run-time terjadi ketika ToInteger diterapkan ke jumlah besar.
Option Strict On
Imports System
Module Program
Sub Main(args As String())
' The assignment of m to n causes a compiler error when
' Option Strict is on.
Dim m As Long = 987
'Dim n As Integer = m
' The For Each loop requires the same conversion but
' causes no errors, even when Option Strict is on.
For Each number As Integer In New Long() {45, 3, 987}
Console.Write(number & " ")
Next
Console.WriteLine()
' Output: 45 3 987
' Here a run-time error is raised because 9876543210
' is too large for type Integer.
'For Each number As Integer In New Long() {45, 3, 9876543210}
' Console.Write(number & " ")
'Next
End Sub
End Module
Panggilan IEnumerator
Ketika eksekusi For Eachperulangan ...Next dimulai, Visual Basic memverifikasi yang group mengacu pada objek koleksi yang valid. Jika tidak, itu melemparkan pengecualian. Jika tidak, ia memanggil MoveNext metode dan Current properti objek enumerator untuk mengembalikan elemen pertama. Jika MoveNext menunjukkan bahwa tidak ada elemen berikutnya, yaitu, jika koleksi kosong, For Each perulangan berhenti dan kontrol diteruskan ke pernyataan setelah Next pernyataan. Jika tidak, Visual Basic mengatur element ke elemen pertama dan menjalankan blok pernyataan.
Setiap kali Visual Basic menemukan Next pernyataan, visual Basic akan kembali ke For Each pernyataan. Sekali lagi ia memanggil MoveNext dan Current untuk mengembalikan elemen berikutnya, dan sekali lagi ia menjalankan blok atau menghentikan perulangan tergantung pada hasilnya. Proses ini berlanjut sampai MoveNext menunjukkan bahwa tidak ada elemen berikutnya atau pernyataan yang Exit For ditemui.
Memodifikasi Koleksi. Objek enumerator yang dikembalikan GetEnumerator biasanya tidak memungkinkan Anda mengubah koleksi dengan menambahkan, menghapus, mengganti, atau menyusun ulang elemen apa pun. Jika Anda mengubah koleksi setelah Anda memulai For Eachperulangan ...Next , objek enumerator menjadi tidak valid, dan upaya berikutnya untuk mengakses elemen menyebabkan InvalidOperationException pengecualian.
Namun, pemblokiran modifikasi ini tidak ditentukan oleh Visual Basic, melainkan oleh implementasi IEnumerable antarmuka. Dimungkinkan untuk menerapkan IEnumerable dengan cara yang memungkinkan modifikasi selama iterasi. Jika Anda mempertimbangkan untuk melakukan modifikasi dinamis seperti itu, pastikan Anda memahami karakteristik IEnumerable implementasi pada koleksi yang Anda gunakan.
Memodifikasi Elemen Koleksi. Properti Current objek enumerator adalah ReadOnly, dan mengembalikan salinan lokal dari setiap elemen koleksi. Ini berarti bahwa Anda tidak dapat memodifikasi elemen itu sendiri dalam For Eachperulangan ...Next . Setiap modifikasi yang Anda buat hanya memengaruhi salinan lokal dari Current dan tidak tercermin kembali ke dalam koleksi yang mendasar. Namun, jika elemen adalah jenis referensi, Anda dapat memodifikasi anggota instans yang ditujukannya. Contoh berikut memodifikasi BackColor anggota setiap thisControl elemen. Namun, Anda tidak dapat memodifikasi thisControl dirinya sendiri.
Sub LightBlueBackground(thisForm As System.Windows.Forms.Form)
For Each thisControl In thisForm.Controls
thisControl.BackColor = System.Drawing.Color.LightBlue
Next thisControl
End Sub
Contoh sebelumnya dapat memodifikasi BackColor anggota setiap thisControl elemen, meskipun tidak dapat memodifikasi thisControl dirinya sendiri.
Melintas Array.
Array Karena kelas mengimplementasikan IEnumerable antarmuka, semua array mengekspos GetEnumerator metode . Ini berarti bahwa Anda dapat melakukan iterasi melalui array dengan For Eachperulangan ...Next . Namun, Anda hanya dapat membaca elemen array. Anda tidak dapat mengubahnya.
Contoh 1
Contoh berikut mencantumkan semua folder di direktori C:\ dengan menggunakan DirectoryInfo kelas .
Dim dInfo As New System.IO.DirectoryInfo("c:\")
For Each dir As System.IO.DirectoryInfo In dInfo.GetDirectories()
Debug.WriteLine(dir.Name)
Next
Contoh 2
Contoh berikut mengilustrasikan prosedur untuk mengurutkan koleksi. Contoh mengurutkan instans Car kelas yang disimpan dalam List<T>. Kelas Car mengimplementasikan antarmuka IComparable<T>, yang mengharuskan metode CompareTo diimplementasikan.
Setiap panggilan ke CompareTo metode membuat perbandingan tunggal yang digunakan untuk pengurutan. Kode yang ditulis pengguna dalam CompareTo metode mengembalikan nilai untuk setiap perbandingan objek saat ini dengan objek lain. Nilai yang dikembalikan kurang dari nol jika objek saat ini kurang dari objek lain, lebih besar dari nol jika objek saat ini lebih besar dari objek lainnya, dan nol jika sama. Ini memungkinkan Anda menentukan dalam kode kriteria untuk lebih besar dari, kurang dari, dan sama dengan.
Dalam metode ListCars, pernyataan cars.Sort() mengurutkan daftar. Panggilan ini ke metode Sort dari List<T> menyebabkan metode CompareTo dipanggil secara otomatis pada objek Car di dalam List.
Public Sub ListCars()
' Create some new cars.
Dim cars As New List(Of Car) From
{
New Car With {.Name = "car1", .Color = "blue", .Speed = 20},
New Car With {.Name = "car2", .Color = "red", .Speed = 50},
New Car With {.Name = "car3", .Color = "green", .Speed = 10},
New Car With {.Name = "car4", .Color = "blue", .Speed = 50},
New Car With {.Name = "car5", .Color = "blue", .Speed = 30},
New Car With {.Name = "car6", .Color = "red", .Speed = 60},
New Car With {.Name = "car7", .Color = "green", .Speed = 50}
}
' Sort the cars by color alphabetically, and then by speed
' in descending order.
cars.Sort()
' View all of the cars.
For Each thisCar As Car In cars
Debug.Write(thisCar.Color.PadRight(5) & " ")
Debug.Write(thisCar.Speed.ToString & " ")
Debug.Write(thisCar.Name)
Debug.WriteLine("")
Next
' Output:
' blue 50 car4
' blue 30 car5
' blue 20 car1
' green 50 car7
' green 10 car3
' red 60 car6
' red 50 car2
End Sub
Public Class Car
Implements IComparable(Of Car)
Public Property Name As String
Public Property Speed As Integer
Public Property Color As String
Public Function CompareTo(ByVal other As Car) As Integer _
Implements System.IComparable(Of Car).CompareTo
' A call to this method makes a single comparison that is
' used for sorting.
' Determine the relative order of the objects being compared.
' Sort by color alphabetically, and then by speed in
' descending order.
' Compare the colors.
Dim compare As Integer
compare = String.Compare(Me.Color, other.Color, True)
' If the colors are the same, compare the speeds.
If compare = 0 Then
compare = Me.Speed.CompareTo(other.Speed)
' Use descending order for speed.
compare = -compare
End If
Return compare
End Function
End Class