Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bir koleksiyondaki her öğe için bir deyim grubunu yineler.
Sözdizimi
For Each element [ As datatype ] In group
[ statements ]
[ Continue For ]
[ statements ]
[ Exit For ]
[ statements ]
Next [ element ]
Parçalar
| Süre | Tanım |
|---|---|
element |
For Each ifadesinde gereklidir. deyiminde Next isteğe bağlı. Değişken. Koleksiyonun öğeleri arasında yineleme yapmak için kullanılır. |
datatype |
İsteğe bağlı ise Option Infer (varsayılan) veya element zaten bildirildiyse; kapalıysa ve element zaten bildirlenmemişse Option Infer gereklidir. veri türü element. |
group |
Gerekli. Koleksiyon türü veya Nesne türüne sahip bir değişken. Üzerinde statements tekrarlanacak olan koleksiyonu ifade eder. |
statements |
Opsiyonel. ile arasında For Each bulunan ve Next içindeki her öğe groupüzerinde çalışan bir veya daha fazla deyim. |
Continue For |
Opsiyonel. Denetimi döngünün başlangıcına For Each aktarır. |
Exit For |
Opsiyonel. Döngünün For Each dışına kontrolü aktarır. |
Next |
Gerekli. Döngünün For Each tanımını sonlandırır. |
Basit Örnek
Bir For Eachkoleksiyonun veya dizinin her öğesi için bir deyim kümesini yinelemek istediğinizde bir ...Next döngüsü kullanın.
Tip
A For... Bir döngünün her yinelemesini bir denetim değişkeniyle ilişkilendirip bu değişkenin ilk ve son değerlerini belirleyebildiğiniz durumlarda Next Deyimi iyi çalışır. Ancak, bir koleksiyonla ilgilenirken, ilk ve son değerler kavramı anlamlı değildir ve koleksiyonun kaç öğeye sahip olduğunu bilmeniz gerekmez. Bu tür bir durumda, bir For Each...Next döngüsü genellikle daha iyi bir seçimdir.
Aşağıdaki örnekte, For Each...
Next deyimi, List koleksiyonunun tüm öğelerinde yinelenir.
' 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
Daha fazla örnek için bkz. Koleksiyonlar ve Diziler.
İç İçe Döngüler
Bir döngünün içine başka bir döngü koyarak döngüleri iç içe For Each yerleştirebilirsiniz.
Aşağıdaki örnekte iç içe yerleştirilmiş For Each...
Next Yapı.
' 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
Döngüleri iç içe yerleştirdiğinizde, her döngünün benzersiz element bir değişkeni olmalıdır.
Ayrıca, farklı türlerde denetim yapılarını da iç içe yerleştirebilirsiniz. Daha fazla bilgi için bkz. İç İçe Denetim Yapıları.
Için Çıkış ve Devam Et
Exit For deyimi yürütmenin For...
Next döngüsünden çıkar ve denetimi Next deyimini izleyen deyime aktarır.
Bu Continue For deyimi, denetimi hemen döngüdeki bir sonraki yinelemesine aktarır. Daha fazla bilgi için bkz. Continue İfadesi.
Aşağıdaki örnekte ve Exit For deyimlerinin nasıl kullanılacağı Continue For gösterilmektedir.
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
Döngüye For Each istediğiniz sayıda Exit For deyim ekleyebilirsiniz. İç içe For Each döngüler içinde kullanıldığında, Exit For yürütmenin en içteki döngüden çıkmasına neden olur ve denetimi bir sonraki üst iç içe yerleştirme düzeyine aktarır.
Exit For genellikle bazı koşullar değerlendirildikten sonra kullanılır, örneğin bir If...Then...Else yapı. Aşağıdaki koşullar için kullanmak Exit For isteyebilirsiniz:
Yinelemeye devam etmek gereksiz veya imkansızdır. Bunun nedeni hatalı bir değer veya sonlandırma isteği olabilir.
Özel durum
Trybir ...Catch...Finally. Bloğun sonundaFinallykullanabilirsinizExit For.Sonsuz bir döngü vardır ve bu döngü çok sayıda hatta sonsuz sayıda çalıştırabilen bir döngüdür. Böyle bir koşul algılarsanız, döngüden kaçmak için kullanabilirsiniz
Exit For. Daha fazla bilgi için Do... Döngü İfadesi bölümüne bakın.
Yineleyiciler
Bir koleksiyon üzerinde özel yineleme gerçekleştirmek için yineleyici kullanırsınız. Yineleyici bir işlev veya Get erişimci olabilir. Koleksiyonun her öğesini birer birer döndürmek için bir Yield deyimini kullanır.
Deyimini kullanarak yineleyici çağırırsınız For Each...Next . Döngünün For Each her yinelemesi yineleyiciyi çağırır. Yineleyicide bir Yield deyime ulaşıldığında, deyimindeki Yield ifade döndürülür ve koddaki geçerli konum korunur. Yineleyici bir sonraki çağrılışında yürütme bu konumdan yeniden başlatılır.
Aşağıdaki örnekte yineleyici işlevi kullanılır. Yineleyici işlevinin for... içinde bir deyimi vardır Yield. Sonraki döngü. yönteminde ListEvenNumbers , deyim gövdesinin For Each her yinelemesi, bir sonraki Yield deyime devam eden yineleyici işlevine bir çağrı oluşturur.
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
Daha fazla bilgi için bkz. Yineleyiciler, Verim Deyimi ve Yineleyici.
Teknik Uygulama
For EachBir ...
Next deyimi çalıştırılır, Visual Basic döngü başlamadan önce koleksiyonu yalnızca bir kez değerlendirir. Deyiminiz veya değişikliklerini elementgroupengellerse, bu değişiklikler döngünün yinelenmesini etkilemez.
Koleksiyondaki tüm öğeler ardışık olarak öğesine atandığında elementFor Each döngü durdurulur ve denetim deyimini izleyen deyimine Next geçer.
Option Infer açıksa (varsayılan ayarı), Visual Basic derleyicisi elementveri türünü çıkarsayabilir. Kapalıysa ve element döngü dışında bildirilmemişse, deyiminde For Each bildirmeniz gerekir. Veri türünü element açıkça bildirmek için bir As yan tümcesi kullanın. Öğenin veri türü ...Next yapısının For Eachdışında tanımlanmadığı sürece, kapsamı döngünün gövdesidir. Döngünün hem dışında hem de içinde bildirimde element bulunamayacağınızı unutmayın.
İsteğe bağlı olarak deyiminde Next belirtebilirsinizelement. Bu, özellikle iç içe For Each döngüleriniz varsa programınızın okunabilirliğini artırır. Karşılık gelen For Each deyimde görünen değişkenle aynı değişkeni belirtmeniz gerekir.
Bir döngünün içindeki değerini element değiştirmekten kaçınmak isteyebilirsiniz. Bunu yapmak kodunuzun okunmasını ve hatalarını ayıklamayı zorlaştırabilir. değerinin group değiştirilmesi, döngüye ilk girildiğinde belirlenen koleksiyonu veya öğelerini etkilemez.
Döngüleri iç içe yerleştirdiğinizde, iç Next düzeyin önünde dış iç içe bir düzeyin Next deyimiyle karşılaşılırsa, derleyici bir hata sinyali gönderir. Derleyici, bu çakışan hatayı yalnızca her bir element deyimde Next belirttiğinizde algılayabilir.
Kodunuz bir koleksiyonu belirli bir sırada geçirmeye bağımlıysa, For Eachkoleksiyonun kullanıma sunmadığı numaralandırıcı nesnesinin özelliklerini bilmiyorsanız...Next döngüsü en iyi seçenek değildir. Geçiş sırası Visual Basic tarafından değil, MoveNext numaralandırıcı nesnesinin yöntemiyle belirlenir. Bu nedenle, koleksiyonun hangi öğesinin içinde elementdöndürülecek ilk öğe olduğunu veya belirli bir öğeden sonra hangi öğenin döndürüleceğini tahmin edemeyebilirsiniz. ...Next veya Do.Loop..gibi Forfarklı bir döngü yapısı kullanarak daha güvenilir sonuçlar elde edebilirsiniz.
Çalışma zamanının içindeki groupelementöğelerini öğesine dönüştürebilmesi gerekir. [Option Strict] deyimi, genişletme ve daraltma dönüştürmelerine izin verilip verilmeyeceğini (Option Strict kapalı, varsayılan değeri) veya yalnızca genişletme dönüştürmelerine izin verilip verilmeyeceğini (Option Strict açık) denetler. Daha fazla bilgi için bkz. Dönüştürmeleri daraltma.
veri türü group , bir koleksiyona veya numaralandırılabilir bir diziye başvuran bir başvuru türü olmalıdır. En yaygın olarak bu, group ad alanının arabirimini veya ad alanının arabirimini System.Collections uygulayan IEnumerable bir nesneye IEnumerable<T> başvururSystem.Collections.Generic.
System.Collections.IEnumerable
GetEnumerator, koleksiyon için bir numaralandırıcı nesnesi döndüren yöntemini tanımlar. Numaralandırıcı nesnesi ad alanının arabirimini uygular System.Collections.IEnumerator ve özelliği ile Reset ve MoveNext yöntemlerini kullanıma sunarCurrent.System.Collections Visual Basic bunları kullanarak koleksiyonun çapraz geçişini kullanır.
Dönüştürmeleri Daraltma
olarak Option Strict ayarlandığında On, dönüştürmeleri daraltmak normalde derleyici hatalarına neden olur. Ancak bir For Each deyimde, içindeki groupelement öğelerden dönüştürmeler çalışma zamanında değerlendirilir ve gerçekleştirilir ve daraltma dönüştürmelerinin neden olduğu derleyici hataları gizlenır.
Aşağıdaki örnekte, öğesinin ilk değeri n olarak ataması m açık olduğunda Option Strict derlenemez çünkü bir'in Long bir'e dönüştürülmesi Integer bir daraltma dönüştürmesidir. Ancak deyiminde For Each , ataması number ile aynı dönüştürmeyi LongIntegergerektirse bile derleyici hatası bildirilmemiştir.
For Each Büyük bir sayı içeren deyiminde, büyük sayıya uygulandığında ToInteger bir çalışma zamanı hatası oluşur.
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
IEnumerator Çağrıları
Bir ...Next döngüsü yürütülmeye For Eachbaşladığında, Visual Basic geçerli bir koleksiyon nesnesine başvuruda bulunduğunu group doğrular. Aksi takdirde, bir özel durum oluşturur. Aksi takdirde, ilk öğeyi MoveNext döndürmek için yöntemini ve Current numaralandırıcı nesnesinin özelliğini çağırır. Bir sonraki öğe olmadığını gösterirse MoveNext , yani koleksiyon boşsa döngü For Each durdurulur ve denetim deyimini izleyen deyimine Next geçer. Aksi takdirde, Visual Basic ilk öğeye ayarlar element ve deyimi bloğunu çalıştırır.
Visual Basic deyimiyle her karşılaştığında Next deyimine For Each döner. Bir sonraki öğeyi döndürmek için ve Current öğesini yeniden çağırır MoveNext ve yine sonucuna bağlı olarak bloğu çalıştırır veya döngünün durdurulur. Bu işlem, bir sonraki öğe olmadığını veya bir deyimle karşılaşıldığını belirtene Exit For kadar MoveNext devam eder.
Koleksiyonu değiştirme. tarafından GetEnumerator döndürülen numaralandırıcı nesnesi normalde öğeleri ekleyerek, silerek, değiştirerek veya yeniden sıralayarak koleksiyonu değiştirmenize izin vermez. Bir For Each...Next döngüsü başlattıktan sonra koleksiyonu değiştirirseniz, numaralandırıcı nesnesi geçersiz hale gelir ve bir sonraki öğeye erişme girişimi bir InvalidOperationException özel duruma neden olur.
Ancak, bu değişikliğin engellenmesi Visual Basic tarafından değil, arabirimin uygulanması tarafından IEnumerable belirlenir. Yineleme sırasında değişikliğe izin veren bir şekilde uygulamak IEnumerable mümkündür. Böyle bir dinamik değişiklik yapmayı düşünüyorsanız, kullandığınız koleksiyondaki uygulamanın özelliklerini IEnumerable anladığınızdan emin olun.
Koleksiyon Öğelerini Değiştirme.
Current Numaralandırıcı nesnesinin özelliği ReadOnly'dir ve her koleksiyon öğesinin yerel bir kopyasını döndürür. Bu, öğeleri bir ...Next döngüsünde For Eachdeğiştiremeyeceğiniz anlamına gelir. Yaptığınız değişiklikler yalnızca yerel kopyayı Current etkiler ve temel alınan koleksiyona geri yansıtılamaz. Ancak, bir öğe bir başvuru türüyse, işaret ettiği örneğin üyelerini değiştirebilirsiniz. Aşağıdaki örnek, her thisControl öğenin üyesini değiştirirBackColor. Ancak, kendisini değiştiremezsiniz thisControl .
Sub LightBlueBackground(thisForm As System.Windows.Forms.Form)
For Each thisControl In thisForm.Controls
thisControl.BackColor = System.Drawing.Color.LightBlue
Next thisControl
End Sub
Önceki örnek, kendisini değiştiremese BackColor de her thisControl öğenin üyesini değiştirebilir thisControl .
Dizileri Geçirme.
Array sınıfı arabirimini uyguladığındanIEnumerable, tüm diziler yöntemini kullanıma sunarGetEnumerator. Bu, bir dizide ...Next döngüsüyle For Eachyineleme yapabileceğiniz anlamına gelir. Ancak, yalnızca dizi öğelerini okuyabilirsiniz. Bunları değiştiremezsiniz.
Örnek 1
Aşağıdaki örnek, sınıfını kullanarak DirectoryInfo C:\ dizinindeki tüm klasörleri listeler.
Dim dInfo As New System.IO.DirectoryInfo("c:\")
For Each dir As System.IO.DirectoryInfo In dInfo.GetDirectories()
Debug.WriteLine(dir.Name)
Next
Örnek 2
Aşağıdaki örnekte bir koleksiyonu sıralama yordamı gösterilmektedir. Örnek, içinde depolanan List<T>bir Car sınıfın örneklerini sıralar.
Car sınıfı, IComparable<T> arabirimini uygular ki bu, CompareTo yönteminin uygulanmasını gerektirir.
yöntemine yapılan CompareTo her çağrı, sıralama için kullanılan tek bir karşılaştırma yapar. yönteminde CompareTo kullanıcı tarafından yazılan kod, geçerli nesnenin başka bir nesneyle her karşılaştırması için bir değer döndürür. Döndürülen değer, geçerli nesne diğer nesneden küçükse sıfırdan küçük, geçerli nesne diğer nesneden büyükse sıfırdan büyük ve eşitse sıfırdan büyük olur. Bu, kodda büyüktür, küçüktür ve eşittir ölçütlerini tanımlamanızı sağlar.
yönteminde ListCarscars.Sort() deyimi listeyi sıralar. Bu çağrı Sort yöntemine, List<T> içindeki CompareTo nesneleri için Car yönteminin otomatik olarak çağrılmasına List neden olur.
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