Aracılığıyla paylaş


Deyimler - Visual Basic

Deyimler yürütülebilir kodu temsil eder.

Statement
    : LabelDeclarationStatement
    | LocalDeclarationStatement
    | WithStatement
    | SyncLockStatement
    | EventStatement
    | AssignmentStatement
    | InvocationStatement
    | ConditionalStatement
    | LoopStatement
    | ErrorHandlingStatement
    | BranchStatement
    | ArrayHandlingStatement
    | UsingStatement
	| AwaitStatement
	| YieldStatement
    ;

Not. Microsoft Visual Basic Derleyicisi yalnızca bir anahtar sözcük veya tanımlayıcı ile başlayan deyimlere izin verir. Bu nedenle, örneğin, "Call (Console).WriteLine" çağırma deyimine izin verilir, ancak "(Console).WriteLine" çağırma deyimi izin verilmez.

Denetim Akışı

Denetim akışı , deyimlerin ve ifadelerin yürütüldiği sıradır. Yürütme sırası belirli bir deyime veya ifadeye bağlıdır.

Örneğin, bir toplama işlecini (Bölüm Ekleme İşleci) değerlendirirken önce sol işlenen, sonra sağ işlenen ve sonra işlecin kendisi değerlendirilir. Bloklar yürütülür (Bölüm Blokları ve Etiketler), önce ilk alt durumları yürütülür ve ardından bloğun deyimleri aracılığıyla tek tek ilerletilir.

Bu sıralamada örtük olan, yürütülecek bir sonraki işlem olan bir denetim noktası kavramıdır. Bir yöntem çağrıldığında (veya "çağrıldığında"), yönteminin bir örneğini oluşturduğunu söyleriz. Yöntem örneği, yöntemin parametrelerinin ve yerel değişkenlerinin kendi kopyasından ve kendi denetim noktasından oluşur.

Normal Yöntemler

Aşağıda normal bir yöntem örneği verilmiştir

Function Test() As Integer
    Console.WriteLine("hello")
    Return 1
End Function

Dim x = Test()    ' invokes the function, prints "hello", assigns 1 to x

Normal bir yöntem çağrıldığında,

  1. İlk olarak yöntemin bir örneği bu çağrıya özgü olarak oluşturulur. Bu örnek, yöntemin tüm parametrelerinin ve yerel değişkenlerinin bir kopyasını içerir.
  2. Ardından, tüm parametreleri sağlanan değerlere ve tüm yerel değişkenleri kendi türlerinin varsayılan değerlerine başlatılır.
  3. durumunda, türü işlevin Functiondönüş türü olan ve ilk değeri varsayılan türü olan işlevin adı olan işlev dönüş değişkeni olarak adlandırılan örtük bir yerel değişken de başlatılır.
  4. Yöntem örneğinin denetim noktası daha sonra yöntem gövdesinin ilk deyiminde ayarlanır ve yöntem gövdesi hemen oradan yürütülmeye başlar (Bölüm Blokları ve Etiketler).

Denetim akışı normal şekilde yöntem gövdesinden çıktığında - veya sonuna ulaşarak End FunctionEnd Sub veya açık ReturnExit veya deyim aracılığıyla - denetim akışı yöntem örneğinin çağırana geri döner. Bir işlev dönüş değişkeni varsa, çağrının sonucu bu değişkenin son değeridir.

Denetim akışı işlenmeyen bir özel durum aracılığıyla yöntem gövdesinden çıktığında, bu özel durum çağırana yayılır.

Denetim akışından çıkıldıktan sonra, yöntem örneğine artık canlı başvuru yoktur. Yöntem örneği, yerel değişkenlerin veya parametrelerin kopyasına yönelik tek başvuruları tuttuysa, bunlar çöp olarak toplanabilir.

Yineleyici Yöntemleri

Yineleyici yöntemleri, deyimi tarafından For Each kullanılabilecek bir dizi oluşturmak için kullanışlı bir yol olarak kullanılır. Yineleyici yöntemleri, dizi öğelerini sağlamak için deyimini (Bölüm Verim Deyimi) kullanırYield. (Deyimi olmayan Yield bir yineleyici yöntemi boş bir dizi oluşturur). Yineleyici yöntemi örneği aşağıda verilmiştir:

Iterator Function Test() As IEnumerable(Of Integer)
    Console.WriteLine("hello")
    Yield 1
    Yield 2
End Function

Dim en = Test()
For Each x In en          ' prints "hello" before the first x
    Console.WriteLine(x)  ' prints "1" and then "2"
Next

Dönüş türü IEnumerator(Of T)olan bir yineleyici yöntemi çağrıldığında,

  1. İlk olarak yineleyici yönteminin bir örneği bu çağrıya özgü olarak oluşturulur. Bu örnek, yöntemin tüm parametrelerinin ve yerel değişkenlerinin bir kopyasını içerir.
  2. Ardından, tüm parametreleri sağlanan değerlere ve tüm yerel değişkenleri kendi türlerinin varsayılan değerlerine başlatılır.
  3. Türü ve ilk değeri varsayılan türü olan Tyineleyici geçerli değişkeni olarak adlandırılan örtük bir yerel değişken de başlatılır.
  4. Ardından yöntem örneğinin denetim noktası, yöntem gövdesinin ilk deyiminde ayarlanır.
  5. Ardından bu yöntem örneğiyle ilişkilendirilmiş bir yineleyici nesnesi oluşturulur. Yineleyici nesnesi bildirilen dönüş türünü uygular ve aşağıda açıklandığı gibi davranışa sahiptir.
  6. Denetim akışı daha sonra çağıranda hemen sürdürülür ve çağrının sonucu yineleyici nesnesidir. Bu aktarımın yineleyici yöntem örneğinden çıkmadan yapıldığını ve finally işleyicilerinin yürütülmesine neden olmadığını unutmayın. Yöntem örneğine yineleyici nesnesi tarafından başvurulmaya devam eder ve yineleyici nesnesine canlı başvuru olduğu sürece çöp toplanmaz.

Yineleyici nesnesinin Current özelliğine erişildiğinde, çağırmanın geçerli değişkeni döndürülür.

Yineleyici nesnesinin MoveNext yöntemi çağrıldığında, çağrı yeni bir yöntem örneği oluşturmaz. Bunun yerine mevcut yöntem örneği kullanılır (ve denetim noktası ile yerel değişkenler ve parametreler) - yineleyici yöntemi ilk kez çağrıldığında oluşturulan örnek. Denetim akışı, yürütmeyi bu yöntem örneğinin denetim noktasında sürdürür ve yineleyici yönteminin gövdesinde normal şekilde ilerler.

Yineleyici nesnesinin Dispose yöntemi çağrıldığında, yine mevcut yöntem örneği kullanılır. Denetim akışı, bu yöntem örneğinin denetim noktasında devam eder, ancak hemen bir Exit Function deyim sonraki işlemmiş gibi davranır.

Bir yineleyici nesnesinde MoveNext veya Dispose çağrısı için yukarıdaki davranış açıklamaları, yalnızca önceki veya bu yineleyici nesnedeki tüm çağrıları MoveNextDispose çağıranlara zaten döndürülmüşse geçerlidir. Henüz yapmadılarsa, davranış tanımlanmamıştır.

Denetim akışı, yineleyici yöntemi gövdesinden normal olarak çıktığı zaman ( bu işaret ucuna ulaşarak End Function veya açık Return veya Exit deyim aracılığıyla) yineleyici yöntemi örneğini sürdürmek için yineleyici nesnesindeki veya Dispose işlevinin çağrılması MoveNext bağlamında bunu yapmış olması gerekir ve yineleyici yöntemi ilk çağrıldığında oluşturulan yöntem örneğini kullanacaktır. Bu örneğin denetim noktası deyiminde End Function bırakılır ve denetim akışı çağıranda devam eder ve bir çağrısı MoveNext tarafından sürdürüldüyse, değer False çağırana döndürülür.

Denetim akışı işlenmeyen bir özel durum aracılığıyla yineleyici yöntemi gövdesinden çıktığında, özel durum çağırana yayılır ve bu da MoveNext veya Disposeçağrısı olur.

Yineleyici işlevinin diğer olası dönüş türlerine gelince,

  • Dönüş türü IEnumerable(Of T) bazıları Tiçin olan bir yineleyici yöntemi çağrıldığında, yöntemdeki tüm parametrelerden ilk olarak yineleyici yönteminin çağrılması için bir örnek oluşturulur ve bunlar sağlanan değerlerle başlatılır. Çağırmanın sonucu, dönüş türünü uygulayan bir nesnedir. Bu nesnenin GetEnumerator yöntemi çağrılırsa, yöntemindeki tüm parametreler ve yerel değişkenler için bu çağrıya GetEnumerator özgü bir örnek oluşturur. Önceden kaydedilmiş olan değerlerin parametrelerini başlatır ve yukarıdaki yineleyici yöntemine göre devam eder.
  • Dönüş türü genel olmayan arabirim IEnumeratorolan bir yineleyici yöntemi çağrıldığında, davranış tam olarak için IEnumerator(Of Object)olduğu gibi olur.
  • Dönüş türü genel olmayan arabirim IEnumerableolan bir yineleyici yöntemi çağrıldığında, davranış tam olarak için IEnumerable(Of Object)olduğu gibi olur.

Asenkron Yöntemler

Zaman uyumsuz yöntemler, örneğin bir uygulamanın kullanıcı arabirimini engellemeden uzun süre çalışan işler yapmak için kullanışlı bir yoldur. Async, Zaman Uyumsuz'un kısaltmasıdır. Bu, zaman uyumsuz yöntemi çağıranın yürütmesini hemen sürdüreceği, ancak zaman uyumsuz yöntemin örneğinin son tamamlanmasının gelecekte bir süre sonra gerçekleşebileceği anlamına gelir. Kurala göre zaman uyumsuz yöntemler "Async" sonekiyle adlandırılır.

Async Function TestAsync() As Task(Of String)
    Console.WriteLine("hello")
    Await Task.Delay(100)
    Return "world"
End Function

Dim t = TestAsync()         ' prints "hello"
Console.WriteLine(Await t)  ' prints "world"

Not. Zaman uyumsuz yöntemler arka plan iş parçacığında çalıştırılmaz . Bunun yerine bir yöntemin kendisini işleç aracılığıyla askıya almasına Await ve bazı olaylara yanıt olarak sürdürülecek şekilde zamanlamasına izin verir.

Zaman uyumsuz bir yöntem çağrıldığında

  1. İlk olarak, bu çağrıya özgü bir zaman uyumsuz yöntem örneği oluşturulur. Bu örnek, yöntemin tüm parametrelerinin ve yerel değişkenlerinin bir kopyasını içerir.
  2. Ardından, tüm parametreleri sağlanan değerlere ve tüm yerel değişkenleri kendi türlerinin varsayılan değerlerine başlatılır.
  3. Bazıları için dönüş türüne Task(Of T) sahip zaman uyumsuz bir yöntem söz konusu olduğunda, türü T ve ilk değeri varsayılan Tdeğeri olan görev dönüş değişkeni olarak adlandırılan örtük bir yerel değişken de başlatılır.T
  4. Zaman uyumsuz yöntem Function dönüş türüne Task sahip veya Task(Of T) bazıları Tiçin ise, geçerli çağrıyla ilişkili örtük olarak bu türdeki bir nesne oluşturulur. Bu, zaman uyumsuz nesne olarak adlandırılır ve zaman uyumsuz yöntemin örneği yürütülerek yapılacak gelecekteki çalışmayı temsil eder. Bu zaman uyumsuz yöntem örneğinin çağırıcısında denetim devam ettiğinde, çağıran bu zaman uyumsuz nesneyi çağrısının sonucu olarak alır.
  5. Örneğin denetim noktası daha sonra zaman uyumsuz yöntem gövdesinin ilk deyiminde ayarlanır ve hemen yöntem gövdesini oradan yürütmeye başlar (Bölüm Blokları ve Etiketler).

Resumption Delegate ve Current Caller

Section Await İşleci'nde ayrıntılı olarak açıklandığı gibi, bir Await ifadenin yürütülmesi, yöntem örneğinin denetim noktasını askıya alma ve denetim akışını başka bir yere gitmeye bırakma özelliğine sahiptir. Denetim akışı daha sonra bir yeniden başlatma temsilcisi çağrılırsa aynı örneğin denetim noktasında devam edebilir. Bu askıya alma işleminin zaman uyumsuz yöntemden çıkmadan yapıldığını ve son işleyicilerin yürütülmesine neden olmadığını unutmayın. Yöntem örneğine yine hem yeniden sağlama temsilcisi hem Task de veya Task(Of T) sonucu (varsa) tarafından başvurulur ve temsilci veya sonuç için canlı başvuru olduğu sürece çöp toplanmaz.

Deyimi Dim x = Await WorkAsync() aşağıdakiler için yaklaşık olarak söz dizimsel kısaltma olarak hayal etmek yararlı olur:

Dim temp = WorkAsync().GetAwaiter()
If Not temp.IsCompleted Then
       temp.OnCompleted(resumptionDelegate)
       Return [task]
       CONT:   ' invocation of 'resumptionDelegate' will resume here
End If
Dim x = temp.GetResult()

Aşağıda, yöntem örneğinin geçerli çağıranı özgün çağıran veya yeniden sağlama temsilcisinin çağıranı (hangisi daha yeniyse) olarak tanımlanır.

Denetim akışı zaman uyumsuz yöntem gövdesinden çıktığında (veya sonuna ulaşarak End Sub ya da End Function açık Return veya deyim aracılığıyla ya da Exit işlenmeyen bir özel durum aracılığıyla) örneğin denetim noktası yöntemin sonuna ayarlanır. Ardından davranış, zaman uyumsuz yöntemin dönüş türüne bağlıdır.

  • dönüş türüne Tasksahip bir Async Function durumunda:

    1. Denetim akışı işlenmeyen bir özel durumdan çıkarsa, zaman uyumsuz nesnenin durumu olarak ayarlanır TaskStatus.Faulted ve Exception.InnerException özelliği özel duruma ayarlanır (şunun dışında: bunu olarak değiştirme TaskStatus.Canceledgibi OperationCanceledException uygulama tanımlı özel durumlar hariç). Denetim akışı geçerli arayanda devam eder.

    2. Aksi takdirde, zaman uyumsuz nesnenin durumu olarak TaskStatus.Completedayarlanır. Denetim akışı geçerli arayanda devam eder.

      (Not. Görevin tüm noktası ve zaman uyumsuz yöntemleri ilginç kılan şey, bir görev Tamamlandı olduğunda, onu bekleyen tüm yöntemlerin şu anda yeniden başlatma temsilcilerinin yürütülmesidir, yani engelleri kaldırılır.)

  • Bazıları Tiçin dönüş türüne Task(Of T) sahip bir Async Function durumunda : davranış yukarıdaki gibidir, ancak özel durum olmayan durumlarda zaman uyumsuz nesnenin Result özelliği de görev dönüş değişkeninin son değerine ayarlanır.

  • durumunda Async Sub:

    1. Denetim akışı işlenmeyen bir özel durumdan çıkarsa, bu özel durum uygulamaya özgü bir şekilde ortama yayılır. Denetim akışı geçerli arayanda devam eder.
    2. Aksi takdirde denetim akışı yalnızca geçerli çağıranda sürdürülür.

Zaman Uyumsuz Alt

Microsoft'a özgü bir Async Subdavranışı vardır.

Çağrının başındaysa SynchronizationContext.CurrentNothing , zaman uyumsuz alt öğeden işlenmeyen özel durumlar Threadpool'a postalanır.

Çağrının başında değilse SynchronizationContext.CurrentNothing , OperationStarted() yöntemin başlangıcından önce ve OperationCompleted() sonundan sonra bu bağlamda çağrılır. Ayrıca, işlenmeyen özel durumlar eşitleme bağlamında yeniden oluşturulacak şekilde deftere nakledilir.

Bu, UI uygulamalarında, ui iş parçacığında çağrılan bir Async Sub için, işleyemediği tüm özel durumların UI iş parçacığının yeniden paylaşılacağı anlamına gelir.

Zaman uyumsuz ve yineleyici yöntemlerinde değiştirilebilir yapılar

Genel olarak değiştirilebilir yapılar hatalı uygulama olarak kabul edilir ve zaman uyumsuz veya yineleyici yöntemler tarafından desteklenmez. Özellikle, bir yapıdaki bir zaman uyumsuz veya yineleyici yönteminin her çağrısı, söz konusu yapının çağırma anında kopyalanan bir kopyası üzerinde örtük olarak çalışır. Bu nedenle, örneğin,

Structure S
       Dim x As Integer
       Async Sub Mutate()
           x = 2
       End Sub
End Structure

Dim s As New S With {.x = 1}
s.Mutate()
Console.WriteLine(s.x)   ' prints "1"

Bloklar ve Etiketler

Yürütülebilir deyimler grubuna deyim bloğu adı verilir. Bir deyim bloğunun yürütülmesi, bloktaki ilk deyimle başlar. Bir deyim yürütüldükten sonra, bir deyim yürütmeyi başka bir yere aktarmadığı veya bir özel durum oluşmadığı sürece sözcük düzenindeki sonraki deyim yürütülür.

Bir deyim bloğu içinde, mantıksal satırlardaki deyimlerin bölünmesi, etiket bildirim deyimleri dışında önemli değildir. Etiket, gibi GoTobir dal deyiminin hedefi olarak kullanılabilecek deyim bloğu içinde belirli bir konumu tanımlayan bir tanımlayıcıdır.

Block
    : Statements*
    ;

LabelDeclarationStatement
    : LabelName ':'
    ;

LabelName
    : Identifier
    | IntLiteral
    ;

Statements
    : Statement? ( ':' Statement? )*
    ;

Etiket bildirimi deyimleri mantıksal satırın başında görünmelidir ve etiketler tanımlayıcı veya tamsayı değişmez değeri olabilir. Hem etiket bildirimi deyimleri hem de çağırma deyimleri tek bir tanımlayıcıdan oluşabileceğinden, yerel satırın başındaki tek bir tanımlayıcı her zaman etiket bildirimi deyimi olarak kabul edilir. Aynı mantıksal çizgide hiçbir deyim izlenmiyorsa bile etiket bildirim deyimleri her zaman iki nokta üst üste eklenmelidir.

Etiketlerin kendi bildirim alanları vardır ve diğer tanımlayıcıları engellemez. Aşağıdaki örnek geçerlidir ve ad değişkenini x hem parametre hem de etiket olarak kullanır.

Function F(x As Integer) As Integer
    If x >= 0 Then
        GoTo x
    End If
    x = -x
x: 
    Return x
End Function

Bir etiketin kapsamı, etiketi içeren yöntemin gövdesidir.

Okunabilirlik açısından, birden çok alt ifade içeren deyim üretimleri, alt ifadelerin her biri etiketli bir satırda tek başına olsa bile, bu belirtim içinde tek bir üretim olarak kabul edilir.

Yerel Değişkenler ve Parametreler

Yukarıdaki bölümlerde yöntem örneklerinin nasıl ve ne zaman oluşturulduğu ve bunlarla birlikte bir yöntemin yerel değişkenlerinin ve parametrelerinin kopyaları ayrıntılı olarak anlatılır. Ayrıca, bir döngünün gövdesine her girildiğinde, Bölüm Döngüsü Deyimleri'nde açıklandığı gibi bu döngü içinde bildirilen her yerel değişkenden yeni bir kopya oluşturulur ve yöntem örneği artık önceki kopya yerine yerel değişkeninin bu kopyasını içerir.

Tüm yerel öğeler, türlerinin varsayılan değerine başlatılır. Yerel değişkenlere ve parametrelere her zaman genel erişim sağlanır. Aşağıdaki örnekte gösterildiği gibi, bildiriminden önceki bir metin konumundaki bir yerel değişkene başvurmak bir hatadır:

Class A
    Private i As Integer = 0

    Sub F()
        i = 1
        Dim i As Integer       ' Error, use precedes declaration.
        i = 2
    End Sub

    Sub G()
        Dim a As Integer = 1
        Dim b As Integer = a   ' This is valid.
    End Sub
End Class

Özellikle yukarıdaki yöntemde, F'ya yapılan ilk atama, dış kapsamda bildirilen alana başvurmaz. Bunun yerine, yerel değişkene başvurur ve değişkenin bildiriminden önce metin olarak geldiği için hata verir. yönteminde G , sonraki değişken bildirimi, aynı yerel değişken bildirimi içinde daha önceki bir değişken bildiriminde bildirilen bir yerel değişkene başvurur.

Bir yöntemdeki her blok, yerel değişkenler için bir bildirim alanı oluşturur. Adlar, yöntem gövdesindeki yerel değişken bildirimleri ve en dıştaki bloğun bildirim alanına adları tanıtan yöntemin parametre listesi aracılığıyla bu bildirim alanına eklenir. Bloklar, iç içe yerleştirme aracılığıyla adların gölgelenmesine izin vermez: Bir blokta bir ad bildirildikten sonra, ad iç içe geçmiş bloklarda yeniden işlenmeyebilir.

Bu nedenle, aşağıdaki örnekte F ve G yöntemleri hatalıdır çünkü ad i dış blokta bildirilir ve iç blokta yeniden oluşturulamaz. Ancak, H ve I yöntemleri geçerlidir çünkü ikisi iayrı iç içe olmayan bloklarda bildirilir.

Class A
    Sub F()
        Dim i As Integer = 0
        If True Then
               Dim i As Integer = 1
        End If
    End Sub

    Sub G()
        If True Then
            Dim i As Integer = 0
        End If
        Dim i As Integer = 1
    End Sub 

    Sub H()
        If True Then
            Dim i As Integer = 0
        End If
        If True Then
            Dim i As Integer = 1
        End If
    End Sub

    Sub I() 
        For i As Integer = 0 To 9
            H()
        Next i

        For i As Integer = 0 To 9
            H()
        Next i
    End Sub 
End Class

Yöntem bir işlev olduğunda, yöntem gövdesinin bildirim alanında, işlevin dönüş değerini temsil eden yöntemle aynı ada sahip özel bir yerel değişken örtük olarak bildirilir. Yerel değişken, ifadelerde kullanıldığında özel ad çözümleme semantiğine sahiptir. Yerel değişken, çağırma ifadesi gibi bir yöntem grubu olarak sınıflandırılmış bir ifade bekleyen bir bağlamda kullanılıyorsa, ad yerel değişken yerine işleve çözümleniyor demektir. Örneğin:

Function F(i As Integer) As Integer
    If i = 0 Then
        F = 1        ' Sets the return value.
    Else
        F = F(i - 1) ' Recursive call.
    End If
End Function

Parantezlerin kullanılması belirsiz durumlara neden olabilir (örneğin F(1), F dönüş türü tek boyutlu bir dizi olan bir işlevdir); tüm belirsiz durumlarda ad, yerel değişken yerine işleve çözümlenir. Örneğin:

Function F(i As Integer) As Integer()
    If i = 0 Then
        F = new Integer(2) { 1, 2, 3 }
    Else
        F = F(i - 1) ' Recursive call, not an index.
    End If
End Function

Denetim akışı yöntem gövdesinden ayrıldığında, yerel değişkenin değeri çağırma ifadesine geri geçirilir. Yöntem bir alt yordamsa, böyle örtük bir yerel değişken yoktur ve denetim yalnızca çağırma ifadesine döner.

Yerel Bildirim Deyimleri

Yerel bildirim deyimi yeni bir yerel değişken, yerel sabit veya statik değişken bildirir. Yerel değişkenler ve yerel sabitler , yöntemi kapsamındaki örnek değişkenlerine ve sabitlere eşdeğerdir ve aynı şekilde bildirilir. Statik değişkenler değişkenlere Shared benzer ve değiştirici kullanılarak Static bildirilir.

LocalDeclarationStatement
    : LocalModifier VariableDeclarators StatementTerminator
    ;

LocalModifier
    : 'Static' | 'Dim' | 'Const'
    ;

Statik değişkenler, yönteminin çağrıları arasında değerlerini koruyan yerel değişkenlerdir. Paylaşılan olmayan yöntemler içinde bildirilen statik değişkenler örnek başınadır: yöntemi içeren türün her örneği, statik değişkenin kendi kopyasına sahiptir. Yöntemler içinde Shared bildirilen statik değişkenler türe göredir; tüm örnekler için statik değişkenin yalnızca bir kopyası vardır. Yerel değişkenler yöntemindeki her girdide kendi türünün varsayılan değeriyle başlatılırken, statik değişkenler yalnızca tür veya tür örneği başlatıldığında türünün varsayılan değerine başlatılır. Statik değişkenler yapılarda veya genel yöntemlerde bildirilmeyebilir.

Yerel değişkenler, yerel sabitler ve statik değişkenler her zaman genel erişilebilirliğe sahiptir ve erişilebilirlik değiştiricileri belirtmeyebilir. Yerel bildirim deyiminde tür belirtilmezse, aşağıdaki adımlar yerel bildirimin türünü belirler:

  1. Bildirimin bir tür karakteri varsa, tür karakterinin türü yerel bildirimin türüdür.

  2. Yerel bildirim yerel bir sabitse veya yerel bildirim başlatıcısı olan bir yerel değişkense ve yerel değişken türü çıkarımı kullanılıyorsa, yerel bildirimin türü başlatıcının türünden çıkarılır. Başlatıcı yerel bildirime başvuruyorsa, derleme zamanı hatası oluşur. (Başlatıcıların olması için yerel sabitler gereklidir.)

  3. Katı semantikler kullanılmıyorsa, yerel bildirim deyiminin türü örtük olarak Objectolur.

  4. Aksi takdirde derleme zamanı hatası oluşur.

Dizi boyutu veya dizi türü değiştiricisi olan bir yerel bildirim deyiminde tür belirtilmezse, yerel bildirimin türü belirtilen dereceye sahip bir dizidir ve dizinin öğe türünü belirlemek için önceki adımlar kullanılır. Yerel değişken türü çıkarımı kullanılırsa, başlatıcının türü yerel bildirim deyimiyle aynı dizi şekline (dizi türü değiştiriciler) sahip bir dizi türü olmalıdır. Çıkarsanan öğe türünün yine de bir dizi türü olabileceğini unutmayın. Örneğin:

Option Infer On

Module Test
    Sub Main()
        ' Error: initializer is not an array type
        Dim x() = 1

        ' Type is Integer()
        Dim y() = New Integer() {}

        ' Type is Integer()()
        Dim z() = New Integer()() {}

        ' Type is Integer()()()

        Dim a()() = New Integer()()() {}

        ' Error: initializer does not have same array shape
        Dim b()() = New Integer(,)() {}
    End Sub
End Module

Boş değer atanabilir tür değiştiricisi olan bir yerel bildirim deyiminde tür belirtilmezse, yerel bildirimin türü, çıkarılmış türün null atanabilir sürümü veya zaten null atanabilir bir değer türüyse, çıkarılmış türün kendisidir. Çıkarsanan tür null yapılabilir bir değer türü değilse, derleme zamanı hatası oluşur. Hem null atanabilir tür değiştirici hem de dizi boyutu veya dizi türü değiştiricisi türü olmayan bir yerel bildirim deyimine yerleştirilirse, null atanabilir tür değiştirici dizinin öğe türüne uygulanacak şekilde kabul edilir ve öğe türünü belirlemek için önceki adımlar kullanılır.

Yerel bildirim deyimlerindeki değişken başlatıcılar, bildirimin metin konumuna yerleştirilen atama deyimleriyle eşdeğerdir. Bu nedenle, yürütme yerel bildirim deyimi üzerinde dallanırsa, değişken başlatıcı yürütülmedi. Yerel bildirim deyimi birden çok kez yürütülürse değişken başlatıcısı eşit sayıda yürütülür. Statik değişkenler yalnızca başlatıcılarını ilk kez yürütür. Statik değişken başlatılırken bir özel durum oluşursa statik değişkenin, statik değişkenin türünün varsayılan değeriyle başlatıldığı kabul edilir.

Aşağıdaki örnekte başlatıcıların kullanımı gösterilmektedir:

Module Test
    Sub F()
        Static x As Integer = 5

        Console.WriteLine("Static variable x = " & x)
        x += 1
    End Sub

    Sub Main()
        Dim i As Integer

        For i = 1 to 3
            F()
        Next i

        i = 3
label:
        Dim y As Integer = 8

        If i > 0 Then
            Console.WriteLine("Local variable y = " & y)
            y -= 1
            i -= 1
            GoTo label
        End If
    End Sub
End Module

Bu program şunu yazdırır:

Static variable x = 5
Static variable x = 6
Static variable x = 7
Local variable y = 8
Local variable y = 8
Local variable y = 8

Statik yerel öğelerdeki başlatıcılar iş parçacığı açısından güvenlidir ve başlatma sırasında özel durumlara karşı korunur. Statik yerel başlatıcı sırasında bir özel durum oluşursa, statik yerel varsayılan değerine sahip olur ve başlatılmaz. Statik yerel başlatıcı

Module Test
    Sub F()
        Static x As Integer = 5
    End Sub
End Module

ile eşdeğer

Imports System.Threading
Imports Microsoft.VisualBasic.CompilerServices

Module Test
    Class InitFlag
        Public State As Short
    End Class

    Private xInitFlag As InitFlag = New InitFlag()

    Sub F()
        Dim x As Integer

        If xInitFlag.State <> 1 Then
            Monitor.Enter(xInitFlag)
            Try
                If xInitFlag.State = 0 Then
                    xInitFlag.State = 2
                    x = 5
                Else If xInitFlag.State = 2 Then
                    Throw New IncompleteInitialization()
                End If
            Finally
                xInitFlag.State = 1
                Monitor.Exit(xInitFlag)
            End Try
        End If
    End Sub
End Module

Yerel değişkenler, yerel sabitler ve statik değişkenlerin kapsamı, bildirildiği deyim bloğuna göre belirlenmiştir. Statik değişkenler, adları yöntemin tamamında yalnızca bir kez kullanılabildikleri için özeldir. Örneğin, farklı bloklarda olsalar bile aynı ada sahip iki statik değişken bildirimi belirtmek geçerli değildir.

Örtük Yerel Bildirimler

Yerel bildirim deyimlerine ek olarak, yerel değişkenler de örtük olarak kullanım yoluyla bildirilebilir. Başka bir şeye çözümlenmeyen bir ad kullanan basit ad ifadesi, bu ada göre yerel bir değişken bildirir. Örneğin:

Option Explicit Off

Module Test
    Sub Main()
        x = 10
        y = 20
        Console.WriteLine(x + y)
    End Sub
End Module

Örtük yerel bildirim yalnızca değişken olarak sınıflandırılan bir ifadeyi kabul edebilen ifade bağlamlarında gerçekleşir. Bu kuralın istisnası, bir işlev çağırma ifadesinin, dizin oluşturma ifadesinin veya üye erişim ifadesinin hedefi olduğunda yerel bir değişkenin örtük olarak bildirilmemesidir.

Örtük yerel öğeler, içeren yöntemin başında bildirilir gibi değerlendirilir. Bu nedenle, bir lambda ifadesinin içinde bildiriliyor olsa bile her zaman tüm yöntem gövdesi kapsamına alınır. Örneğin, aşağıdaki kod:

Option Explicit Off 

Module Test
    Sub Main()
        Dim x = Sub()
                    a = 10
                End Sub
        Dim y = Sub()
                    Console.WriteLine(a)
                End Sub

        x()
        y()
    End Sub
End Module

değerini 10yazdırır. Örtük yerel değerler, değişken adına hiçbir tür karakteri eklenmemiş gibi Object yazılır; aksi takdirde değişkenin türü tür karakterinin türüdür. Yerel değişken türü çıkarımı örtük yereller için kullanılmaz.

Derleme ortamı veya tarafından Option Explicitaçık yerel bildirim belirtilirse, tüm yerel değişkenler açıkça bildirilmelidir ve örtük değişken bildirimine izin verilmez.

With Deyimi

Deyimi With , ifadeyi birden çok kez belirtmeden ifadenin üyelerine birden çok başvuru yapılmasını sağlar.

WithStatement
    : 'With' Expression StatementTerminator
      Block?
      'End' 'With' StatementTerminator
    ;

İfade bir değer olarak sınıflandırılmalıdır ve bloğa girdikten sonra bir kez değerlendirilir. Deyim bloğunda With , nokta veya ünlem işaretiyle başlayan bir üye erişim ifadesi veya sözlük erişim ifadesi, ifadenin With önüne alınmış gibi değerlendirilir. Örneğin:

Structure Test
    Public x As Integer

    Function F() As Integer
        Return 10
    End Function
End Structure

Module TestModule
    Sub Main()
        Dim y As Test

        With y
            .x = 10
            Console.WriteLine(.x)
            .x = .F()
        End With
    End Sub
End Module

Bloğun dışından bir With deyim bloğuna dallanma geçersizdir.

SyncLock Deyimi

Deyimi SyncLock , deyimlerin bir ifadede eşitlenmesine olanak tanır ve bu da birden çok yürütme iş parçacığının aynı deyimleri aynı anda yürütmemesini sağlar.

SyncLockStatement
    : 'SyncLock' Expression StatementTerminator
      Block?
      'End' 'SyncLock' StatementTerminator
    ;

İfade bir değer olarak sınıflandırılmalıdır ve bloğa girdikten sonra bir kez değerlendirilir. Bloğu girerken SyncLock yöntemi belirtilen SharedSystem.Threading.Monitor.Enter ifadede çağrılır. Bu, yürütme iş parçacığının ifade tarafından döndürülen nesnede özel kullanım kilidine sahip olana kadar engeller. Bir SyncLock deyimdeki ifadenin türü bir başvuru türü olmalıdır. Örneğin:

Class Test
    Private count As Integer = 0

    Public Function Add() As Integer
        SyncLock Me
            count += 1
            Add = count
        End SyncLock
    End Function

    Public Function Subtract() As Integer
        SyncLock Me
            count -= 1
            Subtract = count
        End SyncLock
    End Function
End Class

Yukarıdaki örnek, belirli bir örnek için aynı anda birden fazla yürütme iş parçacığının count değişkenini ekleyebilmesini veya çıkaramamasını sağlamak için sınıfın Test belirli bir örneğini eşitler.

SyncLock Blok örtük olarak, bloğu ifadede Shared yöntemini System.Threading.Monitor.Exit çağıran Finally bir Try deyim tarafından bulunur. Bu, özel durum oluştuğunda bile kilidin serbest kalmasını sağlar. Sonuç olarak, bloğun dışından bir SyncLock blok içine dallanma geçersizdir ve bir SyncLock blok ve Resume Nextamaçları için Resume tek bir deyim olarak değerlendirilir. Yukarıdaki örnek aşağıdaki kodla eşdeğerdir:

Class Test
    Private count As Integer = 0

    Public Function Add() As Integer
        Try
            System.Threading.Monitor.Enter(Me)

            count += 1
            Add = count
        Finally
            System.Threading.Monitor.Exit(Me)
        End Try
    End Function

    Public Function Subtract() As Integer
        Try
            System.Threading.Monitor.Enter(Me)

            count -= 1
            Subtract = count
        Finally
            System.Threading.Monitor.Exit(Me)
        End Try
    End Function
End Class

Olay Deyimleri

RaiseEvent, AddHandlerve RemoveHandler deyimleri olayları oluşturur ve olayları dinamik olarak işler.

EventStatement
    : RaiseEventStatement
    | AddHandlerStatement
    | RemoveHandlerStatement
    ;

RaiseEvent Deyimi

Deyimi RaiseEvent , olay işleyicilerine belirli bir olayın gerçekleştiğini bildirir.

RaiseEventStatement
    : 'RaiseEvent' IdentifierOrKeyword
      ( OpenParenthesis ArgumentList? CloseParenthesis )? StatementTerminator
    ;

Bir RaiseEvent deyimdeki basit ad ifadesi, üzerinde Meüye araması olarak yorumlanır. Bu nedenle, RaiseEvent x olduğu gibi RaiseEvent Me.xyorumlanır. İfadenin sonucu, sınıfın kendisinde tanımlanan bir olay için olay erişimi olarak sınıflandırılmalıdır; temel türlerde tanımlanan olaylar bir RaiseEvent deyimde kullanılamaz.

deyimi RaiseEvent , varsa sağlanan parametreler kullanılarak olay temsilcisinin yöntemine çağrı Invoke olarak işlenir. Temsilcinin değeri ise Nothingözel durum oluşturulur. Bağımsız değişken yoksa parantezler atlanabilir. Örneğin:

Class Raiser
    Public Event E1(Count As Integer)

    Public Sub Raise()
        Static RaiseCount As Integer = 0

        RaiseCount += 1
        RaiseEvent E1(RaiseCount)
    End Sub
End Class

Module Test
    Private WithEvents x As Raiser

    Private Sub E1Handler(Count As Integer) Handles x.E1
        Console.WriteLine("Raise #" & Count)
    End Sub

    Public Sub Main()
        x = New Raiser
        x.Raise()        ' Prints "Raise #1".
        x.Raise()        ' Prints "Raise #2".
        x.Raise()        ' Prints "Raise #3".
    End Sub
End Module

Yukarıdaki sınıf Raiser aşağıdakine eşdeğerdir:

Class Raiser
    Public Event E1(Count As Integer)

    Public Sub Raise()
        Static RaiseCount As Integer = 0
        Dim TemporaryDelegate As E1EventHandler

        RaiseCount += 1

        ' Use a temporary to avoid a race condition.
        TemporaryDelegate = E1Event
        If Not TemporaryDelegate Is Nothing Then
            TemporaryDelegate.Invoke(RaiseCount)
        End If
    End Sub
End Class

AddHandler ve RemoveHandler Deyimleri

Çoğu olay işleyicisi değişkenler aracılığıyla WithEvents otomatik olarak bağlansa da, çalışma zamanında olay işleyicilerini dinamik olarak eklemek ve kaldırmak gerekebilir. AddHandler ve RemoveHandler deyimleri bunu yapar.

AddHandlerStatement
    : 'AddHandler' Expression Comma Expression StatementTerminator
    ;

RemoveHandlerStatement
    : 'RemoveHandler' Expression Comma Expression StatementTerminator
    ;

Her deyim iki bağımsız değişken alır: ilk bağımsız değişken olay erişimi olarak sınıflandırılmış bir ifade, ikinci bağımsız değişken ise değer olarak sınıflandırılmış bir ifade olmalıdır. İkinci bağımsız değişkenin türü, olay erişimiyle ilişkili temsilci türü olmalıdır. Örneğin:

Public Class Form1
    Public Sub New()
        ' Add Button1_Click as an event handler for Button1's Click event.
        AddHandler Button1.Click, AddressOf Button1_Click
    End Sub 

    Private Button1 As Button = New Button()

    Sub Button1_Click(sender As Object, e As EventArgs)
        Console.WriteLine("Button1 was clicked!")
    End Sub

    Public Sub Disconnect()
        RemoveHandler Button1.Click, AddressOf Button1_Click
    End Sub
End Class

Bir olay E, verüldüğünde deyimi, olay işleyicisi olarak temsilciyi eklemek veya kaldırmak için örnekte ilgili add_E veya remove_E yöntemi çağırır. Bu nedenle, yukarıdaki kod aşağıdakilerle eşdeğerdir:

Public Class Form1
    Public Sub New()
        Button1.add_Click(AddressOf Button1_Click)
    End Sub 

    Private Button1 As Button = New Button()

    Sub Button1_Click(sender As Object, e As EventArgs)
        Console.WriteLine("Button1 was clicked!")
    End Sub

    Public Sub Disconnect()
        Button1.remove_Click(AddressOf Button1_Click)
    End Sub
End Class

Atama Deyimleri

Atama deyimi bir ifadenin değerini bir değişkene atar. Çeşitli atama türleri vardır.

AssignmentStatement
    : RegularAssignmentStatement
    | CompoundAssignmentStatement
    | MidAssignmentStatement
    ;

Normal Atama Deyimleri

Basit atama deyimi, bir ifadenin sonucunu bir değişkende depolar.

RegularAssignmentStatement
    : Expression Equals Expression StatementTerminator
    ;

Atama işlecinin sol tarafındaki ifade değişken veya özellik erişimi olarak sınıflandırılmalı, atama işlecinin sağ tarafındaki ifade ise değer olarak sınıflandırılmalıdır. İfadenin türü, değişkenin veya özellik erişiminin türüne örtük olarak dönüştürülebilir olmalıdır.

'a atanan değişken bir başvuru türünün dizi öğesiyse, ifadenin dizi öğesi türüyle uyumlu olduğundan emin olmak için bir çalışma zamanı denetimi gerçekleştirilir. Aşağıdaki örnekte, bir örneğinin ArrayList bir dizi öğesinde String depolanamaması nedeniyle son atamanın bir atılması neden olurSystem.ArrayTypeMismatchException.

Dim sa(10) As String
Dim oa As Object() = sa
oa(0) = Nothing         ' This is allowed.
oa(1) = "Hello"         ' This is allowed.
oa(2) = New ArrayList() ' System.ArrayTypeMismatchException is thrown.

Atama işlecinin sol tarafındaki ifade değişken olarak sınıflandırılırsa, atama deyimi değeri değişkende depolar. İfade bir özellik erişimi olarak sınıflandırılırsa, atama deyimi özellik erişimini, değer parametresi yerine değerle birlikte özelliğin erişimcisinin çağrısına Set dönüştürür. Örneğin:

Module Test
    Private PValue As Integer

    Public Property P As Integer
        Get
            Return PValue
        End Get

        Set (Value As Integer)
            PValue = Value
        End Set
    End Property

    Sub Main()
        ' The following two lines are equivalent.
        P = 10
        set_P(10)
    End Sub
End Module

Değişkenin veya özellik erişiminin hedefi bir değer türü olarak yazılıyor ancak değişken olarak sınıflandırılmıyorsa, derleme zamanı hatası oluşur. Örneğin:

Structure S
    Public F As Integer
End Structure

Class C
    Private PValue As S

    Public Property P As S
        Get
            Return PValue
        End Get

        Set (Value As S)
            PValue = Value
        End Set
    End Property
End Class

Module Test
    Sub Main()
        Dim ct As C = New C()
        Dim rt As Object = new C()

        ' Compile-time error: ct.P not classified as variable.
        ct.P.F = 10

        ' Run-time exception.
        rt.P.F = 10
    End Sub
End Module

Atamanın semantiğinin atandığı değişkenin veya özelliğin türüne bağlı olduğunu unutmayın. Atandığı değişken bir değer türüyse, atama ifadenin değerini değişkenine kopyalar. Atandığı değişken bir başvuru türüyse, atama değerin kendisini değil başvuruyu değişkene kopyalar. değişkeninin türü ise Objectatama semantiği, değerin türünün çalışma zamanında bir değer türü mü yoksa başvuru türü mü olduğuna göre belirlenir.

Not. ve Dategibi iç türler için Integer başvuru ve değer atama semantiği aynıdır çünkü türler sabittir. Sonuç olarak, dil kutulu iç türlerde başvuru atamasını iyileştirme olarak kullanabilir. Değer açısından bakıldığında sonuç aynıdır.

Eşittir karakteri (=) hem atama hem de eşitlik için kullanıldığından, gibi x = y.ToString()durumlarda basit atama ile çağırma deyimi arasında bir belirsizlik vardır. Bu gibi durumlarda, atama deyimi eşitlik işlecinden önceliklidir. Bu, örnek ifadenin yerine (x = y).ToString()olarak x = (y.ToString()) yorumlandığı anlamına gelir.

Bileşik Atama Deyimleri

Bileşik atama deyimi formu V op= E alır (burada op geçerli bir ikili işleçtir).

CompoundAssignmentStatement
    : Expression CompoundBinaryOperator LineTerminator? Expression StatementTerminator
    ;

CompoundBinaryOperator
    : '^' '=' | '*' '=' | '/' '=' | '\\' '=' | '+' '=' | '-' '='
    | '&' '=' | '<' '<' '=' | '>' '>' '='
    ;

Atama işlecinin sol tarafındaki ifade değişken veya özellik erişimi olarak sınıflandırılmalı, atama işlecinin sağ tarafındaki ifade ise değer olarak sınıflandırılmalıdır. Bileşik atama deyimi, bileşik atama işlecinin sol tarafındaki değişkenin yalnızca bir kez değerlendirildiğinden farkı olan deyimiyle V = V op E eşdeğerdir. Aşağıdaki örnekte bu fark gösterilmektedir:

Module Test
    Function GetIndex() As Integer
        Console.WriteLine("Getting index")
        Return 1
    End Function

    Sub Main()
        Dim a(2) As Integer

        Console.WriteLine("Simple assignment")
        a(GetIndex()) = a(GetIndex()) + 1

        Console.WriteLine("Compound assignment")
        a(GetIndex()) += 1
    End Sub
End Module

İfade a(GetIndex()) basit atama için iki kez değerlendirilir, ancak bileşik atama için yalnızca bir kez değerlendirilir, bu nedenle kod yazdırılır:

Simple assignment
Getting index
Getting index
Compound assignment
Getting index

Mid Assignment Deyimi

Atama Mid deyimi başka bir dizeye bir dize atar. Atamanın sol tarafında işlevine Microsoft.VisualBasic.Strings.Midyapılan çağrıyla aynı söz dizimi bulunur.

MidAssignmentStatement
    : 'Mid' '$'? OpenParenthesis Expression Comma Expression
      ( Comma Expression )? CloseParenthesis Equals Expression StatementTerminator
    ;

İlk bağımsız değişken atamanın hedefidir ve türü örtük olarak ve 'den Stringdönüştürülebilir olan bir değişken veya özellik erişimi olarak sınıflandırılmalıdır. İkinci parametre, atamanın hedef dizede başlaması gereken yere karşılık gelen ve türü örtük olarak dönüştürülebilir Integerolması gereken bir değer olarak sınıflandırılması gereken 1 tabanlı başlangıç konumudur. İsteğe bağlı üçüncü parametre, sağ taraftaki değerden hedef dizeye atanacak karakter sayısıdır ve türü örtük olarak dönüştürülebilir Integerolan bir değer olarak sınıflandırılmalıdır. Sağ taraf kaynak dizedir ve türü örtük olarak dönüştürülebilir Stringolan bir değer olarak sınıflandırılmalıdır. Sağ taraf, belirtilirse length parametresine kesilir ve başlangıç konumundan başlayarak sol taraftaki dizedeki karakterlerin yerini alır. Sağ taraftaki dize üçüncü parametreden daha az karakter içeriyorsa, yalnızca sağ taraftaki dizedeki karakterler kopyalanır.

Aşağıdaki örnekte görüntülenir ab123fg:

Module Test
    Sub Main()
        Dim s1 As String = "abcdefg"
        Dim s2 As String = "1234567"

        Mid$(s1, 3, 3) = s2
        Console.WriteLine(s1)
    End Sub
End Module

Not. Mid ayrılmış bir sözcük değildir.

Çağırma Deyimleri

Çağırma deyimi, isteğe bağlı anahtar sözcüğünden Callönce gelen bir yöntemi çağırır. Çağırma deyimi, işlev çağırma ifadesiyle aynı şekilde işlenir ve aşağıda bazı farklar belirtilir. Çağırma ifadesi bir değer veya geçersiz olarak sınıflandırılmalıdır. Çağırma ifadesinin değerlendirilmesinden kaynaklanan tüm değerler atılır.

Call Anahtar sözcük atlanırsa, çağırma ifadesi bir tanımlayıcı veya anahtar sözcükle veya bir With bloğun içinde ile . başlamalıdır. Bu nedenle, örneğin, "Call 1.ToString()" geçerli bir deyimdir, ancak "1.ToString()" değildir. (İfade bağlamında, çağırma ifadelerinin de tanımlayıcıyla başlamaması gerektiğini unutmayın. Örneğin, "Dim x = 1.ToString()" geçerli bir deyimdir).

Çağırma deyimleri ile çağırma ifadeleri arasında başka bir fark vardır: çağırma deyimi bir bağımsız değişken listesi içeriyorsa, bu her zaman çağrının bağımsız değişken listesi olarak alınır. Aşağıdaki örnekte fark gösterilmektedir:

Module Test
    Sub Main()
        Call {Function() 15}(0)
        ' error: (0) is taken as argument list, but array is not invokable

        Call ({Function() 15}(0))
        ' valid, since the invocation statement has no argument list

        Dim x = {Function() 15}(0)
        ' valid as an expression, since (0) is taken as an array-indexing

        Call f("a")
        ' error: ("a") is taken as argument list to the invocation of f

        Call f()("a")
        ' valid, since () is the argument list for the invocation of f

        Dim y = f("a")
        ' valid as an expression, since f("a") is interpreted as f()("a")
    End Sub

    Sub f() As Func(Of String,String)
        Return Function(x) x
    End Sub
End Module
InvocationStatement
    : 'Call'? InvocationExpression StatementTerminator
    ;

Koşullu Deyimler

Koşullu deyimler, çalışma zamanında değerlendirilen ifadelere göre deyimlerin koşullu yürütülmesine olanak sağlar.

ConditionalStatement
    : IfStatement
    | SelectStatement
    ;

Eğer... Sonra... Else Deyimleri

Deyim If...Then...Else , temel koşullu deyimdir.

IfStatement
    : BlockIfStatement
    | LineIfThenStatement
    ;

BlockIfStatement
    : 'If' BooleanExpression 'Then'? StatementTerminator
      Block?
      ElseIfStatement*
      ElseStatement?
      'End' 'If' StatementTerminator
    ;

ElseIfStatement
    : ElseIf BooleanExpression 'Then'? StatementTerminator
      Block?
    ;

ElseStatement
    : 'Else' StatementTerminator
      Block?
    ;

LineIfThenStatement
    : 'If' BooleanExpression 'Then' Statements ( 'Else' Statements )? StatementTerminator
    ;
    
ElseIf		
	: 'ElseIf'		
	| 'Else' 'If'   
   ;

Bir If...Then...Else deyimdeki her ifade, Bölüm Boole İfadeleri'ne göre bir Boole ifadesi olmalıdır. (Not: Bu, ifadenin Boole türüne sahip olmasını gerektirmez). deyimindeki If ifade true ise, bloğunun içine alınan If deyimler yürütülür. İfade false ise, ifadelerin her biri ElseIf değerlendirilir. İfadelerden ElseIf biri true olarak değerlendirilirse ilgili blok yürütülür. Hiçbir ifade true olarak değerlendirilirse ve bir Else blok varsa, Else blok yürütülür. Blok yürütmeyi tamamladıktan sonra yürütme deyiminin If...Then...Else sonuna geçer.

deyiminin If satır sürümü, ifade ise If yürütülecek tek bir deyim kümesine ve ifade True ise yürütülecek isteğe bağlı bir deyim kümesine Falsesahiptir. Örneğin:

Module Test
    Sub Main()
        Dim a As Integer = 10
        Dim b As Integer = 20

        ' Block If statement.
        If a < b Then
            a = b
        Else
            b = a
        End If

        ' Line If statement
        If a < b Then a = b Else b = a
    End Sub
End Module

If deyiminin satır sürümü ":" değerinden daha az sıkı bağlanır ve söz Else diziminin izin verdiği sözcüksel olarak en yakın söz If dizimine bağlanır. Örneğin, aşağıdaki iki sürüm eşdeğerdir:

If True Then _
If True Then Console.WriteLine("a") Else Console.WriteLine("b") _
Else Console.WriteLine("c") : Console.WriteLine("d")

If True Then
    If True Then
        Console.WriteLine("a")
    Else
        Console.WriteLine("b")
    End If
    Console.WriteLine("c") : Console.WriteLine("d")
End If

Etiket bildirimi deyimleri dışındaki tüm deyimlere, blok deyimleri de dahil olmak üzere bir satır If deyimi içinde izin verilir. Ancak, çok satırlı lambda ifadeleri dışında LineTerminators'ı StatementTerminators olarak kullanamazlar. Örneğin:

' Allowed, since it uses : instead of LineTerminator to separate statements
If b Then With New String("a"(0),5) : Console.WriteLine(.Length) : End With

' Disallowed, since it uses a LineTerminator
If b then With New String("a"(0), 5)
              Console.WriteLine(.Length)
          End With

' Allowed, since it only uses LineTerminator inside a multi-line lambda
If b Then Call Sub()
                   Console.WriteLine("a")
               End Sub.Invoke()

Servis Talebi Deyimlerini Seçin

Deyimi Select Case , ifadenin değerine göre deyimleri yürütür.

SelectStatement
    : 'Select' 'Case'? Expression StatementTerminator
      CaseStatement*
      CaseElseStatement?
      'End' 'Select' StatementTerminator
    ;

CaseStatement
    : 'Case' CaseClauses StatementTerminator
      Block?
    ;

CaseClauses
    : CaseClause ( Comma CaseClause )*
    ;

CaseClause
    : ( 'Is' LineTerminator? )? ComparisonOperator LineTerminator? Expression
    | Expression ( 'To' Expression )?
    ;

ComparisonOperator
    : '=' | '<' '>' | '<' | '>' | '>' '=' | '<' '='
    ;

CaseElseStatement
    : 'Case' 'Else' StatementTerminator
      Block?
    ;

İfade bir değer olarak sınıflandırılmalıdır. Bir Select Case deyim yürütürken, Select ifade önce değerlendirilir ve Case ardından deyimler metin bildirimi sırasına göre değerlendirilir. olarak değerlendirilen True ilk Case deyiminin bloğu yürütülür. Hiçbir Case deyimi değerlendirilirse True ve bir Case Else deyimi varsa, bu blok yürütülür. Bir bloğun yürütülmesi tamamlandıktan sonra yürütme deyiminin Select sonuna geçer.

Bir Case bloğun yürütülmesinin bir sonraki anahtar bölümüne "geçmesine" izin verilmez. Bu, sonlandırıcı bir deyim yanlışlıkla atlandığında diğer dillerde oluşan yaygın bir Case hata sınıfını önler. Aşağıdaki örnekte bu davranış gösterilmektedir:

Module Test
    Sub Main()
        Dim x As Integer = 10

        Select Case x
            Case 5
                Console.WriteLine("x = 5")
            Case 10
                Console.WriteLine("x = 10")
            Case 20 - 10
                Console.WriteLine("x = 20 - 10")
            Case 30
                Console.WriteLine("x = 30")
        End Select
    End Sub
End Module

Kod yazdırır:

x = 10

Case 10 Ancak ve Case 20 - 10 aynı değer için seçin, Case 10 ancak metin olarak önünde Case 20 - 10 olduğundan yürütülür. Sonrakine Case ulaşıldığında, yürütme deyiminden Select sonra devam eder.

Yan Case tümcesi iki form alabilir. Formlardan biri isteğe bağlı Is anahtar sözcük, karşılaştırma işleci ve ifadedir. İfade, ifadenin Select türüne dönüştürülür; ifade örtük olarak ifadenin Select türüne dönüştürülebilir değilse, derleme zamanı hatası oluşur. Select İfade E, karşılaştırma işleci Op ve Case ifade E1 ise, büyük/küçük harf E OP E1 olarak değerlendirilir. işleci iki ifadenin türü için geçerli olmalıdır; aksi takdirde bir derleme zamanı hatası oluşur.

Diğer form isteğe bağlı olarak anahtar sözcüğü To ve ikinci bir ifadeden sonra gelen bir ifadedir. her iki ifade de ifadenin Select türüne dönüştürülür; herhangi bir ifade örtük olarak ifadenin Select türüne dönüştürülebilir değilse, derleme zamanı hatası oluşur. Select İfade iseE, ilk Case ifade olur E1ve ikinci Case ifade ise E2, Case (belirtilmemişseE2) veya (E >= E1) And (E <= E2)olarak E = E1 değerlendirilir. İşleçler iki ifadenin türü için geçerli olmalıdır; aksi takdirde bir derleme zamanı hatası oluşur.

Döngü Deyimleri

Döngü deyimleri, deyimlerin gövdesinde tekrar tekrar yürütülmesine olanak sağlar.

LoopStatement
    : WhileStatement
    | DoLoopStatement
    | ForStatement
    | ForEachStatement
    ;

Döngü gövdesi her girildiğinde, bu gövdede bildirilen tüm yerel değişkenlerin yeni bir kopyası oluşturulur ve değişkenlerin önceki değerlerine başlatılır. Döngü gövdesindeki bir değişkene yapılan tüm başvurular en son yapılan kopyayı kullanır. Bu kod bir örnek gösterir:

Module Test
    Sub Main()
        Dim lambdas As New List(Of Action)
        Dim x = 1

        For i = 1 To 3
            x = i
            Dim y = x
            lambdas.Add(Sub() Console.WriteLine(x & y))
        Next

        For Each lambda In lambdas
            lambda()
        Next
    End Sub
End Module

Kod çıktıyı üretir:

31    32    33

Döngü gövdesi yürütülürken değişkenin geçerli olan kopyasını kullanır. Örneğin, deyimi Dim y = x en son kopyasına y ve özgün kopyasına xbaşvurur. Bir lambda oluşturulduğunda, bir değişkenin oluşturulduğu sırada hangi kopyasının geçerli olduğunu hatırlar. Bu nedenle, her lambda aynı paylaşılan kopyasını x, ancak farklı bir kopyasını ykullanır. Programın sonunda, lambdaları yürütürken, hepsinin başvurduğunu paylaşılan kopyası x artık son değeri 3'tür.

Lambda veya LINQ ifadeleri yoksa döngü girdisinde yeni bir kopyanın yapıldığını bilmenin mümkün olmadığını unutmayın. Aslında, derleyici iyileştirmeleri bu durumda kopya oluşturmaktan kaçınacaktır. Lambdalar veya LINQ ifadeleri içeren bir döngüye GoTo girmenin de geçersiz olduğunu unutmayın.

İken... Bitiş Süresi ve Do... Döngü Deyimleri

Boole While ifadesini temel alan bir veya Do döngü deyimi döngüleri.

WhileStatement
    : 'While' BooleanExpression StatementTerminator
      Block?
      'End' 'While' StatementTerminator
    ;

DoLoopStatement
    : DoTopLoopStatement
    | DoBottomLoopStatement
    ;

DoTopLoopStatement
    : 'Do' ( WhileOrUntil BooleanExpression )? StatementTerminator
      Block?
      'Loop' StatementTerminator
    ;

DoBottomLoopStatement
    : 'Do' StatementTerminator
      Block?
      'Loop' WhileOrUntil BooleanExpression StatementTerminator
    ;

WhileOrUntil
    : 'While' | 'Until'
    ;

While Boole ifadesi true olarak değerlendirdiği sürece döngü deyimi döngü oluşturur; Do döngü deyimi daha karmaşık bir koşul içerebilir. bir ifade anahtar sözcüğün Do arkasına veya anahtar sözcüğün arkasına yerleştirilebilir, ancak her ikisine Loop birden yerleştirilmeyebilir. Boole ifadesi Bölüm Boole İfadeleri'ne göre değerlendirilir. (Not: Bu, ifadenin Boole türüne sahip olmasını gerektirmez). İfade belirtmemek de geçerlidir; bu durumda döngü hiçbir zaman çıkmaz. İfade sonrasında yerleştirilirse Do, döngü bloğu her yinelemede yürütülmeden önce değerlendirilir. İfade sonrasında yerleştirilirse Loop, döngü bloğu her yinelemede yürütüldükten sonra değerlendirilir. Bu nedenle ifadesinin sonra Loop yerleştirilmesi, sonrasındaki yerleştirmeden Dobir döngü daha oluşturur. Aşağıdaki örnekte bu davranış gösterilmektedir:

Module Test
    Sub Main()
        Dim x As Integer

        x = 3
        Do While x = 1
            Console.WriteLine("First loop")
        Loop

        Do
            Console.WriteLine("Second loop")
        Loop While x = 1
    End Sub
End Module

Kod çıktıyı üretir:

Second Loop

İlk döngü durumunda, döngü yürütülmeden önce koşul değerlendirilir. İkinci döngü durumunda koşul, döngü yürütüldükten sonra yürütülür. Koşullu ifadeye bir While anahtar sözcük veya Until anahtar sözcük ön eki eklenmelidir. İlki, koşul false olarak değerlendirilirse döngüye son ve koşul true olarak değerlendirildiğinde ikinci döngüye son verirseniz.

Not. Until ayrılmış bir sözcük değildir.

İçin... Sonraki Deyimler

Deyim For...Next , bir sınır kümesine göre döngü oluşturur. Deyimi For bir döngü denetim değişkeni, alt sınır ifadesi, üst sınır ifadesi ve isteğe bağlı bir adım değeri ifadesi belirtir. Döngü denetim değişkeni, bir tanımlayıcı ve ardından isteğe bağlı As bir yan tümce veya bir ifade ile belirtilir.

ForStatement
    : 'For' LoopControlVariable Equals Expression 'To' Expression
      ( 'Step' Expression )? StatementTerminator
      Block?
      ( 'Next' NextExpressionList? StatementTerminator )?
    ;

LoopControlVariable
    : Identifier ( IdentifierModifiers 'As' TypeName )?
    | Expression
    ;

NextExpressionList
    : Expression ( Comma Expression )*
    ;

Aşağıdaki kurallara göre, döngü denetim değişkeni bu For...Next deyime özgü yeni bir yerel değişkene veya önceden var olan bir değişkene ya da bir ifadeye başvurur.

  • Döngü denetim değişkeni yan tümcesi olan bir As tanımlayıcıysa, tanımlayıcı yan tümcesinde As belirtilen türün yeni bir yerel değişkenini tanımlar ve tüm For döngü kapsamına alınır.

  • Döngü denetim değişkeni yan As tümcesi olmayan bir tanımlayıcıysa, tanımlayıcı ilk olarak basit ad çözümleme kuralları kullanılarak çözümlenir (bkz. Bölüm Basit Ad İfadeleri), ancak tanımlayıcının bu oluşumu kendi içinde ve kendisinde örtük bir yerel değişkenin oluşturulmasına neden olmaz (Bölüm Örtük Yerel Bildirimler).

    • Bu çözüm başarılı olursa ve sonuç değişken olarak sınıflandırılırsa döngü denetim değişkeni önceden var olan değişkendir.

    • Çözümleme başarısız olursa veya çözüm başarılı olursa ve sonuç bir tür olarak sınıflandırılırsa:

      • yerel değişken türü çıkarımı kullanılıyorsa, tanımlayıcı türü tüm döngü kapsamına alınmış ilişkili ve adım ifadelerinden çıkarılmış For yeni bir yerel değişken tanımlar;
      • Yerel değişken türü çıkarımı kullanılmıyorsa ancak örtük yerel bildirim kullanılıyorsa, kapsamı yöntemin tamamı olan örtük bir yerel değişken oluşturulur (Bölüm Örtük Yerel Bildirimler) ve döngü denetim değişkeni bu önceden var olan değişkene başvurur;
      • ne yerel değişken türü çıkarımı ne de örtük yerel bildirimler kullanılmıyorsa, bu bir hatadır.
    • Çözümleme ne tür ne de değişken olarak sınıflandırılan bir şeyle başarılı olursa, bu bir hatadır.

  • Döngü denetim değişkeni bir ifadeyse, ifade değişken olarak sınıflandırılmalıdır.

Döngü denetim değişkeni başka bir kapsayan For...Next deyim tarafından kullanılamaz. Bir For deyiminin döngü denetim değişkeninin türü yinelemenin türünü belirler ve aşağıdakilerden biri olmalıdır:

  • Byte, SByte, , UShort, Short, UInteger, Integer, , ULongLong, Decimal, Single,Double
  • Numaralandırılmış tür
  • Object
  • T Boole ifadesinde kullanılabilecek bir tür olan aşağıdaki işleçlere B sahip bir tür:
Public Shared Operator >= (op1 As T, op2 As T) As B
Public Shared Operator <= (op1 As T, op2 As T) As B
Public Shared Operator - (op1 As T, op2 As T) As T
Public Shared Operator + (op1 As T, op2 As T) As T

İlişkili ve adım ifadeleri, döngü denetim değişkeninin türüne örtük olarak dönüştürülebilir olmalı ve değer olarak sınıflandırılmalıdır. Derleme zamanında, alt sınır, üst sınır ve adım ifadesi türleri arasında en geniş tür seçilerek döngü denetim değişkeninin türü çıkarılır. İki tür arasında genişletme dönüştürmesi yoksa, derleme zamanı hatası oluşur.

Çalışma zamanında, döngü denetim değişkeninin türü ise Object, yinelemenin türü derleme zamanındakiyle aynı şekilde çıkarılır ve iki özel durum vardır. İlk olarak, ilişkili ve adım ifadelerinin tümü tam sayı türündeyse ancak en geniş türe sahip değilse, üç türü de kapsayan en geniş tür çıkarılır. İkinci olarak, döngü denetim değişkeninin türü olarak StringDouble çıkarsanırsa, bunun yerine çıkarılır. Çalışma zamanında hiçbir döngü denetim türü belirlenemezse veya ifadelerden herhangi biri döngü denetim türüne dönüştürülemezse, bir System.InvalidCastException gerçekleşir. Döngünün başında bir döngü denetim türü seçildikten sonra, döngü denetim değişkenindeki değerde yapılan değişikliklerden bağımsız olarak yineleme boyunca aynı tür kullanılır.

Bir For deyimi eşleşen Next bir deyim tarafından kapatılmalıdır. Değişkeni Next olmayan bir deyim en içteki open For deyimiyle eşleşirken, bir veya daha fazla döngü denetimi değişkenine sahip bir Next deyim soldan sağa doğru her değişkenle eşleşen döngülerle eşleşir For . Bir değişken bu noktada en iç içe döngü olmayan bir For döngüyle eşleşiyorsa derleme zamanı hatasıyla sonuçlanır.

Döngünün başında, üç ifade metin düzeninde değerlendirilir ve alt sınır ifadesi döngü denetim değişkenine atanır. Adım değeri atlanırsa, örtük olarak değişmez değeri 1, döngü denetim değişkeninin türüne dönüştürülür. Üç ifade yalnızca döngünün başında değerlendirilir.

Her döngünün başında, denetim değişkeni, adım ifadesi pozitifse bitiş noktasından büyük olup olmadığını veya adım ifadesi negatifse bitiş noktasından küçük olup olmadığını görmek için karşılaştırılır. Bu durumda döngü For sonlandırılır; aksi takdirde döngü bloğu yürütülür. Döngü denetim değişkeni ilkel bir tür değilse, karşılaştırma işleci ifadenin step >= step - step true veya false olup olmadığına göre belirlenir. deyiminde Next , adım değeri denetim değişkenine eklenir ve yürütme döngünün en üstüne döner.

Döngü bloğunun her yinelemesinde döngü denetim değişkeninin yeni bir kopyasının oluşturulmadığını unutmayın. Bu açıdan, For deyiminden For Each farklıdır ( Bölüm For Each... Next Statements).

Döngü dışından bir For döngüye dallanma geçerli değildir.

Her İçin... Sonraki Deyimler

Deyim For Each...Next , bir ifadedeki öğelere göre döngü oluşturur. Deyimi For Each bir döngü denetim değişkeni ve bir numaralandırıcı ifadesi belirtir. Döngü denetim değişkeni, bir tanımlayıcı ve ardından isteğe bağlı As bir yan tümce veya bir ifade ile belirtilir.

ForEachStatement
    : 'For' 'Each' LoopControlVariable 'In' LineTerminator? Expression StatementTerminator
      Block?
      ( 'Next' NextExpressionList? StatementTerminator )?
    ;

Deyimlerle aynı kurallara uyulması For...Next ( Bölüm Için... Sonraki Deyimler), döngü denetim değişkeni her biri için buna özgü yeni bir yerel değişkene başvurur... Sonraki deyim veya önceden var olan bir değişkene veya bir ifadeye.

Numaralandırıcı ifadesi bir değer olarak sınıflandırılmalı ve türü bir koleksiyon türü veya Objectolmalıdır. Numaralandırıcı ifadesinin türü ise Object, tüm işlemler çalışma zamanına kadar ertelenmiş olur. Aksi takdirde, koleksiyonun öğe türünden döngü denetim değişkeninin türüne dönüştürme mevcut olmalıdır.

Döngü denetim değişkeni başka bir kapsayan For Each deyim tarafından kullanılamaz. Bir For Each deyimi eşleşen Next bir deyim tarafından kapatılmalıdır. Next Döngü denetim değişkeni olmayan bir deyim, en içteki açık For Eachile eşleşir. Bir Next veya daha fazla döngü denetimi değişkenine sahip bir deyim, soldan sağa aynı döngü denetim değişkenine For Each sahip döngülerle eşleşecektir. Bir değişken bu noktada en iç içe döngü olmayan bir For Each döngüyle eşleşirse derleme zamanı hatası oluşur.

Bir türün C , şu türlerden biriyse koleksiyon türü olduğu söylenir:

  • Aşağıdakilerin tümü doğrudur:

    • C, türü Edöndüren imzaya GetEnumerator() sahip erişilebilir bir örnek, paylaşılan veya uzantı yöntemi içerir.
    • E , imza MoveNext() ve dönüş türüyle Booleanerişilebilir bir örnek, paylaşılan veya uzantı yöntemi içerir.
    • E , alıcısı olan adlı Current erişilebilir bir örneği veya paylaşılan özelliği içerir. Bu özelliğin türü, koleksiyon türünün öğe türüdür.
  • arabirimini System.Collections.Generic.IEnumerable(Of T)uygular ve bu durumda koleksiyonun öğe türü olarak Tkabul edilir.

  • arabirimini System.Collections.IEnumerableuygular ve bu durumda koleksiyonun öğe türü olarak Objectkabul edilir.

Aşağıda, numaralandırılabilir bir sınıf örneği verilmiştir:

Public Class IntegerCollection
    Private integers(10) As Integer

    Public Class IntegerCollectionEnumerator
        Private collection As IntegerCollection
        Private index As Integer = -1

        Friend Sub New(c As IntegerCollection)
            collection = c
        End Sub

        Public Function MoveNext() As Boolean
            index += 1

            Return index <= 10
        End Function

        Public ReadOnly Property Current As Integer
            Get
                If index < 0 OrElse index > 10 Then
                    Throw New System.InvalidOperationException()
                End If

                Return collection.integers(index)
            End Get
        End Property
    End Class

    Public Sub New()
        Dim i As Integer

        For i = 0 To 10
            integers(i) = I
        Next i
    End Sub

    Public Function GetEnumerator() As IntegerCollectionEnumerator
        Return New IntegerCollectionEnumerator(Me)
    End Function
End Class

Döngü başlamadan önce numaralandırıcı ifadesi değerlendirilir. İfadenin türü tasarım desenini karşılamıyorsa, ifade veya System.Collections.Generic.IEnumerable(Of T)öğesine System.Collections.IEnumerable yayınlanır. İfade türü genel arabirimi uygularsa, derleme zamanında genel arabirim tercih edilir, ancak genel olmayan arabirim çalışma zamanında tercih edilir. İfade türü genel arabirimi birden çok kez uygularsa, deyimi belirsiz kabul edilir ve derleme zamanı hatası oluşur.

Not. Genel arabirim seçildiğinde arabirim yöntemlerine yapılan tüm çağrıların tür parametreleri içereceği anlamına olacağından, geç bağlı durumda genel olmayan arabirim tercih edilir. Çalışma zamanında eşleşen tür bağımsız değişkenlerini bilmek mümkün olmadığından, bu tür tüm çağrıların geç bağlı çağrılar kullanılarak yapılması gerekir. Bu, genel olmayan arabirim derleme zamanı çağrıları kullanılarak çağrılabildiği için genel olmayan arabirimi çağırmaktan daha yavaş olacaktır.

GetEnumerator sonuç değerinde çağrılır ve işlevin dönüş değeri geçici bir değerde depolanır. Ardından her yinelemenin başında geçici MoveNext olarak çağrılır. döndürürse Falsedöngü sonlanır. Aksi takdirde, döngünün her yinelemesi aşağıdaki gibi yürütülür:

  1. Döngü denetim değişkeni yeni bir yerel değişken tanımladıysa (önceden var olan değişken yerine), bu yerel değişkenin yeni bir kopyası oluşturulur. Geçerli yineleme için, döngü bloğundaki tüm başvurular bu kopyaya başvurur.
  2. Current özelliği alınır, döngü denetim değişkeninin türüne zorlamalı (dönüştürmenin örtük veya açık olmasına bakılmaksızın) ve döngü denetim değişkenine atanır.
  3. Döngü bloğu yürütülür.

Not. Dilin sürüm 10.0 ile 11.0 arasında küçük bir davranış değişikliği vardır. 11.0'ın öncesinde, döngünün her yinelemesi için yeni bir yineleme değişkeni oluşturulmadı . Bu fark yalnızca yineleme değişkeni bir lambda veya döngüden sonra çağrılan bir LINQ ifadesi tarafından yakalanırsa gözlemlenebilir:

Dim lambdas As New List(Of Action)
For Each x In {1,2,3}
   lambdas.Add(Sub() Console.WriteLine(x)
Next
lambdas(0).Invoke()
lambdas(1).Invoke()
lambdas(2).Invoke()

Visual Basic 10.0'a kadar bu, derleme zamanında bir uyarı üretir ve "3" sözcüğü üç kez yazdırılır. Bunun nedeni, döngünün tüm yinelemeleri tarafından paylaşılan tek bir "x" değişkeninin olması ve üç lambdanın da aynı "x" değerini yakalaması ve lambdalar yürütülürken 3 sayısını yakalamasıydı. Visual Basic 11.0'da "1, 2, 3" yazdırılır. Bunun nedeni, her lambdanın farklı bir "x" değişkeni yakalamasıdır.

Not. Deyiminde dönüştürme işleci eklemek için uygun bir yer olmadığından dönüştürme açık olsa bile yinelemenin geçerli öğesi döngü denetim değişkeninin türüne dönüştürülür. Öğe türü olduğundanObject, artık kullanılmayan türüyle System.Collections.ArrayListçalışırken bu özellikle zahmetli hale geldi. Bu, çok sayıda döngüde dökümler gerektirebilirdi, ideal olmadığını hissettiğimiz bir şey. İronik bir şekilde genel değerler, System.Collections.Generic.List(Of T)bu tasarım noktasını yeniden düşünmemize neden olabilecek, kesin olarak belirlenmiş bir koleksiyonun oluşturulmasını etkinleştirdi, ancak uyumluluk açısından bu artık değiştirilemez.

deyimine Next ulaşıldığında yürütme, döngünün en üstüne döner. Anahtar sözcüğünden Next sonra bir değişken belirtilirse, sonrasındaki ilk değişkenle For Eachaynı olmalıdır. Örneğin, aşağıdaki kodu göz önünde bulundurun:

Module Test
    Sub Main()
        Dim i As Integer
        Dim c As IntegerCollection = New IntegerCollection()

        For Each i In c
            Console.WriteLine(i)
        Next i
    End Sub
End Module

Aşağıdaki koda eşdeğerdir:

Module Test
    Sub Main()
        Dim i As Integer
        Dim c As IntegerCollection = New IntegerCollection()

        Dim e As IntegerCollection.IntegerCollectionEnumerator

        e = c.GetEnumerator()
        While e.MoveNext()
            i = e.Current

            Console.WriteLine(i)
        End While
    End Sub
End Module

E Numaralandırıcı türü uygularsaSystem.IDisposable, yöntemini çağırarak Dispose döngüden çıktıktan sonra numaralandırıcı atılır. Bu, numaralandırıcı tarafından tutulan kaynakların serbest bırakılmasını sağlar. deyimini For Each içeren yöntem yapılandırılmamış hata işlemeyi kullanmıyorsa, For Each deyimi, temizlemeyi sağlamak için içinde çağrılan yöntemiyle Dispose bir Try deyiminde Finally sarmalanır.

Not. türü System.Array bir koleksiyon türüdür ve tüm dizi türleri türünden türetildiğinden System.Array, bir deyimde herhangi bir For Each dizi türü ifadesine izin verilir. Tek boyutlu diziler için deyimi, For Each dizin 0 ile başlayıp dizin Uzunluğu - 1 ile biten dizin sırasını artırarak dizi öğelerini numaralandırır. Çok boyutlu diziler için önce en sağdaki boyutun dizinleri artırılır.

Örneğin, aşağıdaki kod yazdırır 1 2 3 4:

Module Test
    Sub Main()
        Dim x(,) As Integer = { { 1, 2 }, { 3, 4 } }
        Dim i As Integer

        For Each i In x
            Console.Write(i & " ")
        Next i
    End Sub
End Module

Bloğun dışından bir For Each deyim bloğuna dallanma geçerli değildir.

Exception-Handling Deyimleri

Visual Basic yapılandırılmış özel durum işlemeyi ve yapılandırılmamış özel durum işlemeyi destekler. Bir yöntemde yalnızca bir özel durum işleme stili kullanılabilir, ancak Error deyimi yapılandırılmış özel durum işlemede kullanılabilir. Bir yöntem her iki özel durum işleme stilini de kullanıyorsa, derleme zamanı hatası oluşur.

ErrorHandlingStatement
    : StructuredErrorStatement
    | UnstructuredErrorStatement
    ;

Yapılandırılmış Exception-Handling Deyimleri

Yapılandırılmış özel durum işleme, belirli özel durumların işlendiği açık bloklar bildirerek hataları işleme yöntemidir. Yapılandırılmış özel durum işleme bir Try deyim aracılığıyla yapılır.

StructuredErrorStatement
    : ThrowStatement
    | TryStatement
    ;

TryStatement
    : 'Try' StatementTerminator
      Block?
      CatchStatement*
      FinallyStatement?
      'End' 'Try' StatementTerminator
    ;

Örneğin:

Module Test
    Sub ThrowException()
        Throw New Exception()
    End Sub

    Sub Main()
        Try
            ThrowException()
        Catch e As Exception
            Console.WriteLine("Caught exception!")
        Finally
            Console.WriteLine("Exiting try.")
        End Try
    End Sub
End Module

Deyimi Try üç tür blokdan oluşur: try blokları, catch blokları ve son olarak bloklar. Try bloğu, yürütülecek deyimleri içeren bir deyim bloğudur. Catch bloğu, özel durumu işleyen bir deyim bloğudur. Finally bloğu, bir özel durumun oluşup işlenmediğine Try bakılmaksızın, deyiminden çıkıldığında çalıştırılacak deyimleri içeren bir deyim bloğudur. Try Yalnızca bir deneme bloğu ve bir finally bloğu içerebilen bir deyim, en az bir catch bloğu veya son blok içermelidir. Yürütmeyi, aynı deyimdeki bir catch bloğunun dışında açıkça bir deneme bloğuna aktarmak geçersizdir.

Son Bloklar

Finally Yürütme deyiminin herhangi bir bölümünden Try ayrıldığında her zaman bir blok yürütülür. Bloğu yürütmek Finally için açık bir eylem gerekmez; yürütme deyiminden Try ayrıldığında sistem bloğu otomatik olarak yürütür ve ardından yürütmeyi Finally hedeflenen hedefine aktarır. Blok Finally , yürütmenin deyiminden nasıl ayrıldığından Try bağımsız olarak yürütülür: bloğun Try sonundan, bloğun sonundan Catch , deyiminden Exit Try , deyiminden GoTo veya oluşturulan özel durumu işlemeden.

Zaman uyumsuz bir yöntemdeki ifadenin Await ve Yield yineleyici yöntemindeki deyiminin, denetim akışının zaman uyumsuz veya yineleyici yöntem örneğinde askıya alınmasına ve başka bir yöntem örneğinde sürdürmesine neden olabileceğini unutmayın. Ancak, bu yalnızca yürütmenin askıya alınmasıdır ve ilgili zaman uyumsuz yöntemden veya yineleyici yöntem örneğinden çıkmayı içermez ve bu nedenle blokların yürütülmesine neden Finally olmaz.

Yürütmeyi açıkça bir Finally bloğa aktarmak geçersizdir; bir özel durum dışında yürütmeyi bir Finally blok dışına aktarmak da geçersizdir.

FinallyStatement
    : 'Finally' StatementTerminator
      Block?
    ;

Catch Blokları

Blok işlenirken Try bir özel durum oluşursa, özel durumun işlenip işlenmediğini belirlemek için her Catch deyim metin sırasına göre inceler.

CatchStatement
    : 'Catch' ( Identifier ( 'As' NonArrayTypeName )? )?
	  ( 'When' BooleanExpression )? StatementTerminator
      Block?
    ;

Yan Catch tümcesinde belirtilen tanımlayıcı, oluşan özel durumu temsil eder. Tanımlayıcı bir As yan tümce içeriyorsa, tanımlayıcının bloğun Catch yerel bildirim alanı içinde bildirilmesi kabul edilir. Aksi takdirde tanımlayıcı, bir blok içeren bir blokta tanımlanmış bir yerel değişken (statik değişken değil) olmalıdır.

Catch Tanımlayıcısı olmayan bir yan tümcesi, 'den System.Exceptiontüretilen tüm özel durumları yakalar. Tanımlayıcıya Catch sahip bir yan tümce yalnızca türleri tanımlayıcının türüyle aynı veya türetilmiş özel durumları yakalar. Türün veya System.Exceptiontüründen System.Exceptiontüretilmiş olması gerekir. öğesinden System.Exceptiontüretilen bir özel durum yakalandığında, özel durum nesnesine başvuru işlevi Microsoft.VisualBasic.Information.Errtarafından döndürülen nesnede depolanır.

Yan Catch tümcesi olan yan When tümce yalnızca ifade değerlendirildiğinde Trueözel durumları yakalar; ifadenin türü Bölüm Boole İfadeleri'ne göre bir Boole ifadesi olmalıdır. Yan When tümcesi yalnızca özel durumun türü denetlendikten sonra uygulanır ve bu örnekte gösterildiği gibi ifade özel durumu temsil eden tanımlayıcıya başvurabilir:

Module Test
    Sub Main()
        Dim i As Integer = 5

        Try
            Throw New ArgumentException()
        Catch e As OverflowException When i = 5
            Console.WriteLine("First handler")
        Catch e As ArgumentException When i = 4
            Console.WriteLine("Second handler")
        Catch When i = 5
            Console.WriteLine("Third handler")
        End Try

    End Sub
End Module

Bu örnek şunu yazdırır:

Third handler

Bir Catch yan tümcesi özel durumu işlerse, yürütme bloğuna Catch aktarır. Bloğun Catch sonunda, yürütme deyimini izleyen ilk deyime Try aktarır. deyimi Try , bir Catch blokta oluşan özel durumları işlemez. Hiçbir Catch yan tümce özel durumu işlemezse, yürütme sistem tarafından belirlenen bir konuma aktarılır.

Yürütmeyi açıkça bir Catch bloğa aktarmak geçersizdir.

When yan tümcelerindeki filtreler normalde özel durum atılmadan önce değerlendirilir. Örneğin, aşağıdaki kod "Filter, Finally, Catch" yazdırır.

Sub Main()
   Try
       Foo()
   Catch ex As Exception When F()
       Console.WriteLine("Catch")
   End Try
End Sub

Sub Foo()
    Try
        Throw New Exception
    Finally
        Console.WriteLine("Finally")
    End Try
End Sub

Function F() As Boolean
    Console.WriteLine("Filter")
    Return True
End Function

Ancak, Zaman Uyumsuz ve Yineleyici yöntemleri, içindeki tüm son blokların, dışındaki herhangi bir filtreden önce yürütülmesine neden olur. Örneğin, yukarıdaki kodda varsa Async Sub Foo()çıkış "Finally, Filter, Catch" olur.

Throw Deyimi

deyimi Throw , türünden System.Exceptiontüretilen bir örneğiyle temsil edilen bir özel durum oluşturur.

ThrowStatement
    : 'Throw' Expression? StatementTerminator
    ;

İfade bir değer olarak sınıflandırılmamışsa veya türünden System.Exceptiontüretilmemişse, derleme zamanı hatası oluşur. İfade çalışma zamanında null değer olarak değerlendirilirse bunun yerine bir System.NullReferenceException özel durum oluşturulur.

Bir Throw deyimi, bir deyiminin catch bloğu içindeki ifadeyi Try atlar, ancak araya son blok eklenmez. Bu durumda deyimi, şu anda catch bloğu içinde işlenen özel durumu yeniden oluşturur. Örneğin:

Sub Test(x As Integer)
    Try
        Throw New Exception()
    Catch
        If x = 0 Then
            Throw    ' OK, rethrows exception from above.
        Else
            Try
                If x = 1 Then
                    Throw   ' OK, rethrows exception from above.
                End If
            Finally
                Throw    ' Invalid, inside of a Finally.
            End Try
        End If
    End Try
End Sub

Yapılandırılmamış Exception-Handling Deyimleri

Yapılandırılmamış özel durum işleme, bir özel durum oluştuğunda dallandırılan deyimleri belirterek hataları işleme yöntemidir. Yapılandırılmamış özel durum işleme üç deyim kullanılarak uygulanır: Error deyimi, On Error deyimi ve Resume deyimi.

UnstructuredErrorStatement
    : ErrorStatement
    | OnErrorStatement
    | ResumeStatement
    ;

Örneğin:

Module Test
    Sub ThrowException()
        Error 5
    End Sub

    Sub Main()
        On Error GoTo GotException

        ThrowException()
        Exit Sub

GotException:
        Console.WriteLine("Caught exception!")
        Resume Next
    End Sub
End Module

Bir yöntem yapılandırılmamış özel durum işlemeyi kullandığında, tüm özel durumları yakalayan yöntemin tamamı için tek bir yapılandırılmış özel durum işleyicisi oluşturulur. (Oluşturucularda bu işleyicinin oluşturucunun başında çağrısına yapılan çağrıyı New genişletmediğini unutmayın.) Yöntemi daha sonra en son özel durum işleyici konumunu ve oluşan en son özel durumu izler. yöntemine girişte, özel durum işleyici konumu ve özel durum olarak ayarlanır Nothing. Yapılandırılmamış özel durum işleme kullanan bir yöntemde özel durum oluştuğunda, özel durum nesnesine başvuru işlevi Microsoft.VisualBasic.Information.Errtarafından döndürülen nesnede depolanır.

Yineleyicide veya zaman uyumsuz yöntemlerde yapılandırılmamış hata işleme deyimlerine izin verilmez.

Error Deyimi

Bir Error deyim, Visual Basic 6 özel durum numarası içeren bir özel durum oluşturur System.Exception . İfade bir değer olarak sınıflandırılmalı ve türü örtük olarak olarak olarak Integerdönüştürülebilir olmalıdır.

ErrorStatement
    : 'Error' Expression StatementTerminator
    ;

On Error Deyimi

Deyimi On Error , en son özel durum işleme durumunu değiştirir.

OnErrorStatement
    : 'On' 'Error' ErrorClause StatementTerminator
    ;

ErrorClause
    : 'GoTo' '-' '1'
    | 'GoTo' '0'
    | GoToStatement
    | 'Resume' 'Next'
    ;

Dört yoldan biriyle kullanılabilir:

  • On Error GoTo -1 en son özel durumu olarak Nothingsıfırlar.

  • On Error GoTo 0 en son özel durum işleyici konumunu olarak Nothingsıfırlar.

  • On Error GoTo LabelName etiketi en son özel durum işleyici konumu olarak oluşturur. Bu deyim, lambda veya sorgu ifadesi içeren bir yöntemde kullanılamaz.

  • On Error Resume Next davranışı en Resume Next son özel durum işleyici konumu olarak oluşturur.

Resume Deyimi

Deyimi Resume , en son özel duruma neden olan deyimine yürütme döndürür.

ResumeStatement
    : 'Resume' ResumeClause? StatementTerminator
    ;

ResumeClause
    : 'Next'
    | LabelName
    ;

Next Değiştirici belirtilirse, yürütme, en son özel duruma neden olan deyiminden sonra yürütülecek deyimine döner. Bir etiket adı belirtilirse, yürütme etikete döner.

SyncLock deyimi örtük yapılandırılmış bir hata işleme bloğu Resume içerdiğinden ve Resume Next deyimlerinde SyncLock oluşan özel durumlar için özel davranışlara sahiptir. Resume yürütmeyi deyiminin SyncLock başına döndürürken Resume Next , yürütmeyi deyiminden sonraki SyncLock deyime döndürür. Örneğin, aşağıdaki kodu göz önünde bulundurun:

Class LockClass
End Class

Module Test
    Sub Main()
        Dim FirstTime As Boolean = True
        Dim Lock As LockClass = New LockClass()

        On Error GoTo Handler

        SyncLock Lock
            Console.WriteLine("Before exception")
            Throw New Exception()
            Console.WriteLine("After exception")
        End SyncLock

        Console.WriteLine("After SyncLock")
        Exit Sub

Handler:
        If FirstTime Then
            FirstTime = False
            Resume
        Else
            Resume Next
        End If
    End Sub
End Module

Aşağıdaki sonucu yazdırır.

Before exception
Before exception
After SyncLock

deyimi aracılığıyla SyncLock ilk kez, Resume yürütmeyi deyiminin SyncLock başına döndürür. deyimi aracılığıyla SyncLock ikinci kez, Resume Next deyiminin sonuna yürütme döndürür SyncLock . Resume ve Resume Next bir SyncLock deyim içinde izin verilmez.

Her durumda, bir Resume deyim yürütülürken en son özel durum olarak Nothingayarlanır. Bir Resume deyim en son özel durum olmadan yürütülürse, deyimi Visual Basic hata numarasını 20 (Hata olmadan sürdür) içeren bir System.Exception özel durum oluşturur.

Branch Deyimleri

Branch deyimleri, bir yöntemdeki yürütme akışını değiştirir. Altı dal deyimi vardır:

  1. Deyimi GoTo , yürütmenin yönteminde belirtilen etikete aktarılmasına neden olur. Bir lambda veya LINQ ifadesinde bu bloğun yerel değişkeni yakalanırsa, bir , WithUsingSyncLock, , For veya For Each bloğuna veya herhangi bir döngü bloğuna izin verilmez.GoToTry
  2. Deyimi Exit , belirtilen türdeki block deyimini içeren hemen sonundan sonra yürütmeyi bir sonraki deyime aktarır. Blok yöntem bloğuysa denetim akışı, Bölüm Denetim Akışı'nda açıklandığı gibi yöntemden çıkar. Deyimi, Exit deyiminde belirtilen blok türü içinde yer almadıysa, derleme zamanı hatası oluşur.
  3. Deyimi Continue , yürütmeyi belirtilen türdeki blok döngüsü deyimini içeren hemen sonuna aktarır. Deyimi, Continue deyiminde belirtilen blok türü içinde yer almadıysa, derleme zamanı hatası oluşur.
  4. Deyimi Stop hata ayıklayıcı özel durumunun oluşmasına neden olur.
  5. Deyimi End programı sonlandırır. Sonlandırıcılar kapatmadan önce çalıştırılır, ancak şu anda yürütülen Try deyimlerin son blokları yürütülemez. Bu deyim yürütülebilir olmayan programlarda (örneğin, DLL'ler) kullanılamayabilir.
  6. İfade Return içermeyen bir Exit Sub deyim, or Exit Function deyimiyle eşdeğerdir. İfade Return içeren bir deyime yalnızca işlev olan normal bir yöntemde veya bazı Tiçin dönüş türüne Task(Of T) sahip bir işlev olan zaman uyumsuz bir yöntemde izin verilir. İfade, işlev dönüş değişkenine (normal yöntemler söz konusu olduğunda) veya görev dönüş değişkenine (zaman uyumsuz yöntemler söz konusu olduğunda) örtük olarak dönüştürülebilen bir değer olarak sınıflandırılmalıdır. Davranışı ifadesini değerlendirmek, sonra dönüş değişkeninde depolamak ve ardından örtük Exit Function bir deyim yürütmektir.
BranchStatement
    : GoToStatement
    | ExitStatement
    | ContinueStatement
    | StopStatement
    | EndStatement
    | ReturnStatement
    ;

GoToStatement
    : 'GoTo' LabelName StatementTerminator
    ;

ExitStatement
    : 'Exit' ExitKind StatementTerminator
    ;

ExitKind
    : 'Do' | 'For' | 'While' | 'Select' | 'Sub' | 'Function' | 'Property' | 'Try'
    ;

ContinueStatement
    : 'Continue' ContinueKind StatementTerminator
    ;

ContinueKind
    : 'Do' | 'For' | 'While'
    ;

StopStatement
    : 'Stop' StatementTerminator
    ;

EndStatement
    : 'End' StatementTerminator
    ;

ReturnStatement
    : 'Return' Expression? StatementTerminator
    ;

Array-Handling Deyimleri

İki deyim, dizilerle çalışmayı basitleştirir: ReDim deyimler ve Erase deyimler.

ArrayHandlingStatement
    : RedimStatement
    | EraseStatement
    ;

ReDim Deyimi

Deyimi ReDim yeni dizilerin örneğini oluşturur.

RedimStatement
    : 'ReDim' 'Preserve'? RedimClauses StatementTerminator
    ;

RedimClauses
    : RedimClause ( Comma RedimClause )*
    ;

RedimClause
    : Expression ArraySizeInitializationModifier
    ;

Deyimindeki her yan tümce, türü dizi türü veya olan bir değişken veya Objectözellik erişimi olarak sınıflandırılmalı ve ardından dizi sınırları listesi eklenmelidir. Sınırların sayısı değişkenin türüyle tutarlı olmalıdır; için Objectherhangi bir sayıda sınıra izin verilir. Çalışma zamanında, her ifade için belirtilen sınırlarla soldan sağa bir dizi oluşturulur ve ardından değişkene veya özelliğe atanır. Değişken türü ise Object, boyut sayısı belirtilen boyut sayısıdır ve dizi öğesi türü ise olur Object. Verilen boyut sayısı çalışma zamanında değişken veya özellik ile uyumsuzsa derleme zamanı hatası oluşur. Örneğin:

Module Test
    Sub Main()
        Dim o As Object
        Dim b() As Byte
        Dim i(,) As Integer

        ' The next two statements are equivalent.
        ReDim o(10,30)
        o = New Object(10, 30) {}

        ' The next two statements are equivalent.
        ReDim b(10)
        b = New Byte(10) {}

        ' Error: Incorrect number of dimensions.
        ReDim i(10, 30, 40)
    End Sub
End Module

Preserve Anahtar sözcük belirtilirse, ifadelerin de bir değer olarak sınıflanabilir olması ve en sağdaki hariç her boyut için yeni boyutun mevcut dizinin boyutuyla aynı olması gerekir. Varolan dizideki değerler yeni diziye kopyalanır: yeni dizi daha küçükse, var olan değerler atılır; yeni dizi daha büyükse, ek öğeler dizinin öğe türünün varsayılan değerine başlatılır. Örneğin, aşağıdaki kodu göz önünde bulundurun:

Module Test
    Sub Main()
        Dim x(5, 5) As Integer

        x(3, 3) = 3

        ReDim Preserve x(5, 6)
        Console.WriteLine(x(3, 3) & ", " & x(3, 6))
    End Sub
End Module

Aşağıdaki sonucu yazdırır:

3, 0

Mevcut dizi başvurusu çalışma zamanında null bir değerse hata verilmez. En sağdaki boyut dışında, bir boyutun boyutu değişirse, bir System.ArrayTypeMismatchException oluşturulur.

Not. Preserve ayrılmış bir sözcük değildir.

Erase Deyimi

Deyimi Erase , deyiminde belirtilen dizi değişkenlerinin veya özelliklerin her birini olarak Nothingayarlar. deyimindeki her ifade, türü bir dizi türü veya olan bir değişken veya Objectözellik erişimi olarak sınıflandırılmalıdır. Örneğin:

Module Test
    Sub Main()
        Dim x() As Integer = New Integer(5) {}

        ' The following two statements are equivalent.
        Erase x
        x = Nothing
    End Sub
End Module
EraseStatement
    : 'Erase' EraseExpressions StatementTerminator
    ;

EraseExpressions
    : Expression ( Comma Expression )*
    ;

Using deyimi

Bir koleksiyon çalıştırıldığında ve örneğe canlı başvuru bulunamadığında tür örnekleri çöp toplayıcı tarafından otomatik olarak serbest bırakılır. Bir tür özellikle değerli ve kıt bir kaynakta (veritabanı bağlantıları veya dosya tanıtıcıları gibi) barındırıyorsa, artık kullanımda olmayan türün belirli bir örneğini temizlemek için bir sonraki çöp toplamaya kadar beklemek istenmeyebilir. Bir koleksiyondan önce kaynakları serbest bırakmanın basit bir yolunu sağlamak için, bir tür arabirimi uygulayabilir System.IDisposable . Böyle bir tür, değerli kaynakları hemen serbest bırakılmaya zorlamak için çağrılabilen bir Dispose yöntemi kullanıma sunar, örneğin:

Module Test
    Sub Main()
        Dim x As DBConnection = New DBConnection("...")

        ' Do some work
        ...

        x.Dispose()        ' Free the connection
    End Sub
End Module

deyimi Using , bir kaynak alma, bir deyim kümesi yürütme ve ardından kaynağı yok etme işlemini otomatikleştirir. deyimi iki biçim alabilir: birinde kaynak, deyiminin bir parçası olarak bildirilen ve normal bir yerel değişken bildirim deyimi olarak kabul edilen yerel bir değişkendir; diğerinde, kaynak bir ifadenin sonucudur.

UsingStatement
    : 'Using' UsingResources StatementTerminator
      Block?
      'End' 'Using' StatementTerminator
    ;

UsingResources
    : VariableDeclarators
    | Expression
    ;

Kaynak bir yerel değişken bildirim deyimiyse, yerel değişken bildiriminin türü örtük olarak 'a System.IDisposabledönüştürülebilecek bir tür olmalıdır. Bildirilen yerel değişkenler salt okunur, kapsamı deyim bloğu olarak Using belirlenmiştir ve bir başlatıcı içermelidir. Kaynak bir ifadenin sonucuysa, ifadenin bir değer olarak sınıflandırılması ve örtük olarak 'a System.IDisposabledönüştürülebilecek türde olması gerekir. İfade, deyiminin başında yalnızca bir kez değerlendirilir.

BlokUsing, son bloğu kaynakta yöntemini IDisposable.Dispose çağıran bir Try deyimi tarafından örtük olarak bulunur. Bu, özel durum oluştuğunda bile kaynağın atılmasını sağlar. Sonuç olarak, bloğun dışından bir Using blok içine dallanma geçersizdir ve bir Using blok ve Resume Nextamaçları için Resume tek bir deyim olarak değerlendirilir. Kaynak ise Nothingçağrısı yapılmaz Dispose . Bu nedenle, örnek:

Using f As C = New C()
    ...
End Using

eşdeğerdir:

Dim f As C = New C()
Try
    ...
Finally
    If f IsNot Nothing Then
        f.Dispose()
    End If
End Try

Using Yerel değişken bildirim deyimine sahip bir deyim, aynı anda birden çok kaynak alabilir ve bu da iç içe deyimlere Using eşdeğerdir. Örneğin, formun bir Using deyimi:

Using r1 As R = New R(), r2 As R = New R()
    r1.F()
    r2.F()
End Using

eşdeğerdir:

Using r1 As R = New R()
    Using r2 As R = New R()
        r1.F()
        r2.F()
    End Using
End Using

Await Deyimi

Await deyimi, await işleci ifadesiyle (Section Await İşleci) aynı söz dizimine sahiptir, yalnızca await ifadelerine de izin veren yöntemlerde izin verilir ve await işleci ifadesiyle aynı davranışa sahiptir.

Ancak, değer veya geçersiz olarak sınıflandırılabilir. await işleci ifadesinin değerlendirilmesinden kaynaklanan tüm değerler atılır.

AwaitStatement
    : AwaitOperatorExpression StatementTerminator
    ;

Yield Deyimi

Yield deyimleri, Bölüm Yineleyici Yöntemleri'nde açıklanan yineleyici yöntemleriyle ilgilidir.

YieldStatement
    : 'Yield' Expression StatementTerminator
    ;

Yield, içinde göründüğü hemen kapsayan yöntem veya lambda ifadesinin değiştiricisi varsa ve bu değiştiriciden Yield sonra Iterator görünürse, başka bir yerde ayrılmamışsa ayrılmış bir Iterator sözcük olur. Ayrıca önişlemci yönergelerinde de kaydedilmez. Verim deyimine yalnızca ayrılmış bir sözcük olduğu bir yöntemin veya lambda ifadesinin gövdesinde izin verilir. Hemen kapsayan yöntem veya lambda içinde, verim deyimi bir veya Finally bloğun gövdesinde veya bir CatchSyncLock deyimin gövdesinde gerçekleşmeyebilir.

Yield deyimi, değer olarak sınıflandırılması gereken ve türü örtük olarak yineleyici geçerli değişkeninin türüne (Bölüm Yineleyici Yöntemleri) dönüştürülebilen tek bir ifade alır.

Denetim akışı yalnızca yöntem yineleyici Yield nesnede çağrıldığında MoveNext bir deyime ulaşır. (Bunun nedeni, yineleyici yöntem örneğinin deyimlerini yalnızca yineleyici nesnede çağrılan veya Dispose yöntemleri nedeniyle MoveNext yürütmesi ve yöntemin Dispose yalnızca izin verilmeyen bloklarda FinallyYield kod yürütmesidir).

Bir Yield deyim yürütürken ifadesi değerlendirilir ve yineleyici nesnesiyle ilişkilendirilmiş yineleyici yöntemi örneğinin yineleyici geçerli değişkeninde depolanır. değeri True çağırıcısına MoveNextdöndürülür ve bu örneğin denetim noktası yineleyici nesnesinde sonraki çağrıya MoveNext kadar ilerlemeyi durdurur.