Aracılığıyla paylaş


Tür Üyeleri

Tür üyeleri depolama konumlarını ve yürütülebilir kodu tanımlar. Yöntemler, oluşturucular, olaylar, sabitler, değişkenler ve özellikler olabilir.

Arabirim Yöntemi Uygulaması

Yöntemler, olaylar ve özellikler arabirim üyelerini uygulayabilir. Bir arabirim üyesi uygulamak için üye bildirimi anahtar sözcüğünü Implements belirtir ve bir veya daha fazla arabirim üyesini listeler.

ImplementsClause
    : ( 'Implements' ImplementsList )?
    ;

ImplementsList
    : InterfaceMemberSpecifier ( Comma InterfaceMemberSpecifier )*
    ;

InterfaceMemberSpecifier
    : NonArrayTypeName Period IdentifierOrKeyword
    ;

Arabirim üyelerini uygulayan yöntemler ve özellikler, , Overridableveya başka bir üyenin geçersiz kılındığı bildirilmediği MustOverridesürece örtük olarak NotOverridable yapılır. Arabirim üyesi uygulayan bir üyenin olması bir hatadır Shared. Bir üyenin erişilebilirliğinin, arabirim üyelerini uygulama özelliği üzerinde hiçbir etkisi yoktur.

Bir arabirim uygulamasının geçerli olması için, içeren türün uygulama listesinin uyumlu bir üye içeren bir arabirimi adlandırması gerekir. Uyumlu üye, imzası uygulayan üyenin imzası ile eşleşen üyedir. Genel bir arabirim uygulanıyorsa, Implements yan tümcesinde sağlanan tür bağımsız değişkeni, uyumluluğu denetlerken imzayla değiştirilir. Örneğin:

Interface I1(Of T)
    Sub F(x As T)
End Interface

Class C1
    Implements I1(Of Integer)

    Sub F(x As Integer) Implements I1(Of Integer).F
    End Sub
End Class

Class C2(Of U)
    Implements I1(Of U)

    Sub F(x As U) Implements I1(Of U).F
    End Sub
End Class

Temsilci türü kullanılarak bildirilen bir olay arabirim olayı uyguluyorsa, temel alınan temsilci türü aynı olan uyumlu bir olaydır. Aksi takdirde, olay uyguladığı arabirim olayından temsilci türünü kullanır. Böyle bir olay birden çok arabirim olayı uygularsa, tüm arabirim olaylarının aynı temel temsilci türüne sahip olması gerekir. Örneğin:

Interface ClickEvents
    Event LeftClick(x As Integer, y As Integer)
    Event RightClick(x As Integer, y As Integer)
End Interface

Class Button
    Implements ClickEvents

    ' OK. Signatures match, delegate type = ClickEvents.LeftClickHandler.
    Event LeftClick(x As Integer, y As Integer) _
        Implements ClickEvents.LeftClick

    ' OK. Signatures match, delegate type = ClickEvents.RightClickHandler.
    Event RightClick(x As Integer, y As Integer) _
        Implements ClickEvents.RightClick
End Class

Class Label
    Implements ClickEvents

    ' Error. Signatures match, but can't be both delegate types.
    Event Click(x As Integer, y As Integer) _
        Implements ClickEvents.LeftClick, ClickEvents.RightClick
End Class

Uygulama listesindeki arabirim üyesi bir tür adı, nokta ve tanımlayıcı kullanılarak belirtilir. Tür adı, uygulama listesindeki bir arabirim veya uygulama listesindeki bir arabirimin temel arabirimi ve tanımlayıcı da belirtilen arabirimin üyesi olmalıdır. Tek bir üye birden fazla eşleşen arabirim üyesi uygulayabilir.

Interface ILeft
    Sub F()
End Interface

Interface IRight
    Sub F()
End Interface

Class Test
    Implements ILeft, IRight

    Sub F() Implements ILeft.F, IRight.F
    End Sub
End Class

Uygulanan arabirim üyesi birden çok arabirim devralma nedeniyle açıkça uygulanan tüm arabirimlerde kullanılamıyorsa, uygulayan üye açıkça üyenin kullanılabilir olduğu bir temel arabirime başvurmalıdır. Örneğin, ve bir üye içeriyorsa ve I2I3 öğesinden I1I2devralıyorsa I1 ve uygulayan I3 bir tür ve I2.MuygularI1.M.M Arabirim gölgeleri devralınan üyeleri çarpıyorsa, uygulayan bir türün devralınan üyeleri ve bunları gölgelendiren üyeleri uygulaması gerekir.

Interface ILeft
    Sub F()
End Interface

Interface IRight
    Sub F()
End Interface

Interface ILeftRight
    Inherits ILeft, IRight

    Shadows Sub F()
End Interface

Class Test
    Implements ILeftRight

    Sub LeftF() Implements ILeft.F
    End Sub

    Sub RightF() Implements IRight.F
    End Sub

    Sub LeftRightF() Implements ILeftRight.F
    End Sub
End Class

Uygulanacak arabirim üyesinin içeren arabirimi genelse, uygulanan arabirimle aynı tür bağımsız değişkenler sağlanmalıdır. Örneğin:

Interface I1(Of T)
    Function F() As T
End Interface

Class C1
    Implements I1(Of Integer)
    Implements I1(Of Double)

    Function F1() As Integer Implements I1(Of Integer).F
    End Function

    Function F2() As Double Implements I1(Of Double).F
    End Function

    ' Error: I1(Of String) is not implemented by C1
    Function F3() As String Implements I1(Of String).F
    End Function
End Class

Class C2(Of U)
    Implements I1(Of U)

    Function F() As U Implements I1(Of U).F
    End Function
End Class

Yöntemler

Yöntemler, bir programın yürütülebilir deyimlerini içerir.

MethodMemberDeclaration
    : MethodDeclaration
    | ExternalMethodDeclaration
    ;

InterfaceMethodMemberDeclaration
    : InterfaceMethodDeclaration
    ;

MethodDeclaration
    : SubDeclaration
    | MustOverrideSubDeclaration
    | FunctionDeclaration
    | MustOverrideFunctionDeclaration
    ;

InterfaceMethodDeclaration
    : InterfaceSubDeclaration
    | InterfaceFunctionDeclaration
    ;

SubSignature
    : 'Sub' Identifier TypeParameterList?
      ( OpenParenthesis ParameterList? CloseParenthesis )?
    ;

FunctionSignature
    : 'Function' Identifier TypeParameterList?
      ( OpenParenthesis ParameterList? CloseParenthesis )?
      ( 'As' Attributes? TypeName )?
    ;

SubDeclaration
    : Attributes? ProcedureModifier* SubSignature
      HandlesOrImplements? LineTerminator
      Block
      'End' 'Sub' StatementTerminator
    ;

MustOverrideSubDeclaration
    : Attributes? MustOverrideProcedureModifier+ SubSignature
      HandlesOrImplements? StatementTerminator
    ;

InterfaceSubDeclaration
    : Attributes? InterfaceProcedureModifier* SubSignature StatementTerminator
    ;

FunctionDeclaration
    : Attributes? ProcedureModifier* FunctionSignature
      HandlesOrImplements? LineTerminator
      Block
      'End' 'Function' StatementTerminator
    ;

MustOverrideFunctionDeclaration
    : Attributes? MustOverrideProcedureModifier+ FunctionSignature
      HandlesOrImplements? StatementTerminator
    ;

InterfaceFunctionDeclaration
    : Attributes? InterfaceProcedureModifier* FunctionSignature StatementTerminator
    ;

ProcedureModifier
    : AccessModifier | 'Shadows' | 'Shared' | 'Overridable' | 'NotOverridable' | 'Overrides'
    | 'Overloads' | 'Partial' | 'Iterator' | 'Async'
    ;

MustOverrideProcedureModifier
    : ProcedureModifier
    | 'MustOverride'
    ;

InterfaceProcedureModifier
    : 'Shadows' | 'Overloads'
    ;

HandlesOrImplements
    : HandlesClause
    | ImplementsClause
    ;

İsteğe bağlı parametre listesine ve isteğe bağlı dönüş değerine sahip yöntemler paylaşılır veya paylaşılmaz. Paylaşılan yöntemlere sınıfı veya sınıfın örnekleri aracılığıyla erişilir. Örnek yöntemleri olarak da adlandırılan paylaşılmayan yöntemlere sınıfın örnekleri aracılığıyla erişilir. Aşağıdaki örnekte, birkaç paylaşılan yöntem (Clone ve ) ve Flipbirkaç örnek yöntemi (Push, Popve ToString) içeren bir sınıf Stack gösterilmektedir:

Public Class Stack
    Public Shared Function Clone(s As Stack) As Stack
        ...
    End Function

    Public Shared Function Flip(s As Stack) As Stack
        ...
    End Function

    Public Function Pop() As Object
        ...
    End Function

    Public Sub Push(o As Object)
        ...
    End Sub 

    Public Overrides Function ToString() As String
        ...
    End Function 
End Class 

Module Test
    Sub Main()
        Dim s As Stack = New Stack()
        Dim i As Integer

        While i < 10
            s.Push(i)
        End While

        Dim flipped As Stack = Stack.Flip(s)
        Dim cloned As Stack = Stack.Clone(s)

        Console.WriteLine("Original stack: " & s.ToString())
        Console.WriteLine("Flipped stack: " & flipped.ToString())
        Console.WriteLine("Cloned stack: " & cloned.ToString())
    End Sub
End Module

Yöntemler aşırı yüklenebilir, bu da birden çok yöntemin benzersiz imzaları olduğu sürece aynı ada sahip olabileceği anlamına gelir. Bir yöntemin imzası, parametrelerinin sayısından ve türlerinden oluşur. Bir yöntemin imzası özellikle dönüş türünü veya Optional, ByRef veya ParamArray gibi parametre değiştiricilerini içermez. Aşağıdaki örnekte bir dizi aşırı yükleme içeren bir sınıf gösterilmektedir:

Module Test
    Sub F()
        Console.WriteLine("F()")
    End Sub 

    Sub F(o As Object)
        Console.WriteLine("F(Object)")
    End Sub

    Sub F(value As Integer)
        Console.WriteLine("F(Integer)")
    End Sub 

    Sub F(a As Integer, b As Integer)
        Console.WriteLine("F(Integer, Integer)")
    End Sub 

    Sub F(values() As Integer)
        Console.WriteLine("F(Integer())")
    End Sub 

    Sub G(s As String, Optional s2 As String = 5)
        Console.WriteLine("G(String, Optional String")
    End Sub

    Sub G(s As String)
        Console.WriteLine("G(String)")
    End Sub


    Sub Main()
        F()
        F(1)
        F(CType(1, Object))
        F(1, 2)
        F(New Integer() { 1, 2, 3 })
        G("hello")
        G("hello", "world")
    End Sub
End Module

Programın çıktısı:

F()
F(Integer)
F(Object)
F(Integer, Integer)
F(Integer())
G(String)
G(String, Optional String)

Yalnızca isteğe bağlı parametrelerde farklılık gösteren aşırı yüklemeler, kitaplıkların "sürümü oluşturma" için kullanılabilir. Örneğin, kitaplığın v1'i isteğe bağlı parametrelere sahip bir işlev içerebilir:

Sub fopen(fileName As String, Optional accessMode as Integer = 0)

Daha sonra kitaplığın v2'sinde başka bir isteğe bağlı "parola" parametresi eklemek ve bunu kaynak uyumluluğunu bozmadan (v1'i hedeflemek için kullanılan uygulamalar yeniden derlenebilir) ve ikili uyumluluğu bozmadan yapmak ister (bu nedenle v1'e başvurmak için kullanılan uygulamalar artık yeniden derleme olmadan v2'ye başvurabilir). v2 şöyle görünür:

Sub fopen(file As String, mode as Integer)
Sub fopen(file As String, Optional mode as Integer = 0, Optional pword As String = "")

Genel API'deki isteğe bağlı parametrelerin CLS uyumlu olmadığını unutmayın. Ancak, bunlar en azından Visual Basic ve C#4 ve F# tarafından kullanılabilir.

Normal, Zaman Uyumsuz ve Yineleyici Yöntem Bildirimleri

İki tür yöntem vardır: değer döndürmeyen alt yordamlar ve döndüren işlevler. Bir yöntemin gövdesi ve End yapısı yalnızca yöntem bir arabirimde tanımlanmışsa veya değiştiriciye MustOverride sahipse atlanabilir. Bir işlevde dönüş türü belirtilmezse ve katı semantikler kullanılıyorsa derleme zamanı hatası oluşur; aksi takdirde türü örtük Object veya yöntemin tür karakterinin türüdür. Bir yöntemin dönüş türünün ve parametre türlerinin erişilebilirlik etki alanı, yöntemin erişilebilirlik etki alanının üst kümesiyle aynı veya üst kümesi olmalıdır.

Normal yöntem, ne de AsyncIterator değiştiricisi olan bir yöntemdir. Bir alt yordam veya işlev olabilir. Normal Yöntemler bölümü, normal bir yöntem çağrıldığında ne olacağını ayrıntılarıyla açıklar.

Yineleyici yöntemi, değiştiricisi Iterator olan ve değiştirici olmayan Async yöntemdir. Bir işlev olmalı ve dönüş türü , veya IEnumerator(Of T) bazılarında Tolmalıdır ve parametresi olmamalıdırByRef.IEnumerable(Of T)IEnumerableIEnumerator Bölüm Yineleyici Yöntemleri, yineleyici yöntemi çağrıldığında ne olacağını ayrıntılarıyla açıklar.

Zaman uyumsuz yöntem, değiştiricisi Async olan ve değiştiricisi olmayan Iterator yöntemdir. Bir alt yordam veya dönüş türüne Task sahip bir işlev ya da Task(Of T) bazı Tiçin olmalıdır ve parametresi olmamalıdır ByRef . Bölüm Zaman Uyumsuz Yöntemler , zaman uyumsuz bir yöntem çağrıldığında ne olacağını ayrıntılarıyla açıklar.

Bir yöntem bu üç yöntemden biri değilse, derleme zamanı hatasıdır.

Alt yordam ve işlev bildirimleri, başlangıç ve bitiş deyimlerinin her birinin mantıksal çizginin başında başlaması gerektiği için özeldir. Buna ek olarak, alt yordam veya işlev olmayanMustOverride bir bildirimin gövdesi mantıksal satırın başında başlamalıdır. Örneğin:

Module Test
    ' Illegal: Subroutine doesn't start the line
    Public x As Integer : Sub F() : End Sub

    ' Illegal: First statement doesn't start the line
    Sub G() : Console.WriteLine("G")
    End Sub

    ' Illegal: End Sub doesn't start the line
    Sub H() : End Sub
End Module

Dış Yöntem Bildirimleri

Dış yöntem bildirimi, uygulaması program dışında sağlanan yeni bir yöntem tanıtır.

ExternalMethodDeclaration
    : ExternalSubDeclaration
    | ExternalFunctionDeclaration
    ;

ExternalSubDeclaration
    : Attributes? ExternalMethodModifier* 'Declare' CharsetModifier? 'Sub'
      Identifier LibraryClause AliasClause?
      ( OpenParenthesis ParameterList? CloseParenthesis )? StatementTerminator
    ;

ExternalFunctionDeclaration
    : Attributes? ExternalMethodModifier* 'Declare' CharsetModifier? 'Function'
      Identifier LibraryClause AliasClause?
      ( OpenParenthesis ParameterList? CloseParenthesis )?
      ( 'As' Attributes? TypeName )?
      StatementTerminator
    ;

ExternalMethodModifier
    : AccessModifier
    | 'Shadows'
    | 'Overloads'
    ;

CharsetModifier
    : 'Ansi' | 'Unicode' | 'Auto'
    ;

LibraryClause
    : 'Lib' StringLiteral
    ;

AliasClause
    : 'Alias' StringLiteral
    ;

Bir dış yöntem bildirimi gerçek bir uygulama sağlamadığından, yöntem gövdesi veya End yapısı yoktur. Dış yöntemler örtük olarak paylaşılır, tür parametrelerine sahip olmayabilir ve olayları işleymeyebilir veya arabirim üyelerini uygulamayabilir. bir işlevde dönüş türü belirtilmezse ve katı semantikler kullanılıyorsa, derleme zamanı hatası oluşur. Aksi takdirde tür örtük olarak Object veya yöntemin tür karakterinin türüdür. Bir dış yöntemin dönüş türünün ve parametre türlerinin erişilebilirlik etki alanı, dış yöntemin erişilebilirlik etki alanının üst kümesiyle aynı veya üst kümesi olmalıdır.

Bir dış yöntem bildiriminin library yan tümcesi, yöntemini uygulayan dış dosyanın adını belirtir. İsteğe bağlı diğer ad yan tümcesi, dış dosyadaki yöntemin sayısal sıralı (karakter ön ekli) veya adını belirten bir # dizedir. Dış yönteme çağrı sırasında dizeleri sıralamak için kullanılan karakter kümesini yöneten tek karakterli bir küme değiştirici de belirtilebilir. Değiştirici Unicode tüm dizeleri Unicode değerlerine göre sıralar, Ansi değiştirici tüm dizeleri ANSI değerlerine sıralar ve Auto değiştirici de dizeleri yöntemin adına veya belirtilirse diğer ad adına göre .NET Framework kurallarına göre sıralar. Değiştirici belirtilmezse, varsayılan değer olur Ansi.

veya Unicode belirtilirseAnsi, yöntem adı değişiklik yapılmadan dış dosyada aranılır. Belirtilirse Auto yöntem adı araması platforma bağlıdır. Platform ANSI (örneğin, Windows 95, Windows 98, Windows ME) olarak kabul edilirse, yöntem adı değişiklik yapılmadan aranılır. Arama başarısız olursa, bir A eklenir ve arama yeniden denendi. Platform Unicode (örneğin, Windows NT, Windows 2000, Windows XP) olarak kabul edilirse, bir W eklenir ve ad aranılır. Arama başarısız olursa, arama olmadan Wyeniden denenecektir. Örneğin:

Module Test
    ' All platforms bind to "ExternSub".
    Declare Ansi Sub ExternSub Lib "ExternDLL" ()

    ' All platforms bind to "ExternSub".
    Declare Unicode Sub ExternSub Lib "ExternDLL" ()

    ' ANSI platforms: bind to "ExternSub" then "ExternSubA".
    ' Unicode platforms: bind to "ExternSubW" then "ExternSub".
    Declare Auto Sub ExternSub Lib "ExternDLL" ()
End Module

Dış yöntemlere geçirilen veri türleri tek bir özel durumla .NET Framework veri hazırlama kurallarına göre sıralanır. Değer (başka bir ifadeyle ByVal x As String) geçirilen dize değişkenleri OLE Otomasyonu BSTR türüne sıralanır ve dış yöntemde BSTR'de yapılan değişiklikler dize bağımsız değişkenine geri yansıtılır. Bunun nedeni, dış yöntemlerdeki türün String değiştirilebilir olması ve bu özel sıralamanın bu davranışı taklit ediyor olmasıdır. Başvuru (örneğin ByRef x As String) tarafından geçirilen dize parametreleri, OLE Otomasyonu BSTR türüne yönelik bir işaretçi olarak sıralanır. parametresinde özniteliğini belirterek System.Runtime.InteropServices.MarshalAsAttribute bu özel davranışları geçersiz kılmak mümkündür.

Örnekte dış yöntemlerin kullanımı gösterilmektedir:

Class Path
    Declare Function CreateDirectory Lib "kernel32" ( _
        Name As String, sa As SecurityAttributes) As Boolean
    Declare Function RemoveDirectory Lib "kernel32" ( _
        Name As String) As Boolean
    Declare Function GetCurrentDirectory Lib "kernel32" ( _
        BufSize As Integer, Buf As String) As Integer
    Declare Function SetCurrentDirectory Lib "kernel32" ( _
        Name As String) As Boolean
End Class

Geçersiz Kılınabilir Yöntemler

Değiştirici, Overridable bir yöntemin geçersiz kılınabilir olduğunu gösterir. Değiştirici, Overrides bir yöntemin aynı imzaya sahip temel tür geçersiz kılınabilir bir yöntemi geçersiz kıldığını gösterir. Değiştirici, NotOverridable geçersiz kılınabilir bir yöntemin daha fazla geçersiz kılınamayacağını gösterir. Değiştirici, MustOverride türetilmiş sınıflarda bir yöntemin geçersiz kılınması gerektiğini gösterir.

Bu değiştiricilerin belirli bileşimleri geçerli değildir:

  • Overridable ve NotOverridable birbirini dışlar ve birleştirilemez.

  • MustOverride ifade eder Overridable (ve belirtemez) ve ile NotOverridablebirleştirilemez.

  • NotOverridableveya MustOverride ile Overridable birleştirilemez ve ile Overridesbirleştirilmelidir.

  • Overrides ifade eder Overridable (ve belirtemez) ve ile MustOverridebirleştirilemez.

Geçersiz kılınabilir yöntemlerle ilgili ek kısıtlamalar da vardır:

  • Yöntem MustOverride bir yöntem gövdesi veya yapısı içermeyebilir, başka bir End yöntemi geçersiz kılabilir ve yalnızca sınıflarda MustInherit görünebilir.

  • Bir yöntem belirtirse Overrides ve geçersiz kılınacak eşleşen bir temel yöntem yoksa, derleme zamanı hatası oluşur. Geçersiz kılma yöntemi belirtmeyebilir Shadows.

  • Geçersiz kılma yönteminin erişilebilirlik etki alanı geçersiz kılınan yöntemin erişilebilirlik etki alanına eşit değilse, yöntem başka bir yöntemi geçersiz kılmayabilir. Tek özel durum, erişimi olmayan Friend başka bir derlemedeki bir Protected Friend yöntemi geçersiz kılma yönteminin belirtmesi Protected gerektiğidir (belirtmemelidirProtected Friend).

  • Privateyöntemleri , , NotOverridableveya MustOverrideveya olamazlar Overridableya da diğer yöntemleri geçersiz kılamazlar.

  • Sınıflardaki NotInheritable yöntemler veya MustOverrideolarak bildirilmeyebilirOverridable.

Aşağıdaki örnekte geçersiz kılınabilir ve geçersiz kılınamaz yöntemler arasındaki farklar gösterilmektedir:

Class Base
    Public Sub F()
        Console.WriteLine("Base.F")
    End Sub

    Public Overridable Sub G()
        Console.WriteLine("Base.G")
    End Sub
End Class

Class Derived
    Inherits Base

    Public Shadows Sub F()
        Console.WriteLine("Derived.F")
    End Sub

    Public Overrides Sub G()
        Console.WriteLine("Derived.G")
    End Sub
End Class

Module Test
    Sub Main()
        Dim d As Derived = New Derived()
        Dim b As Base = d

        b.F()
        d.F()
        b.G()
        d.G()
    End Sub
End Module

Örnekte, sınıfı Base bir yöntem F ve bir Overridable yöntem Gtanıtır. sınıfı Derived yeni bir yöntem Ftanıtır, böylece devralınan Föğesini gölgeler ve devralınan yöntemi Ggeçersiz kılar. Örnek aşağıdaki çıkışı oluşturur:

Base.F
Derived.F
Derived.G
Derived.G

b.G() değil Derived.G, Base.G çağırdığını fark edin. Bunun nedeni, örneğin derleme zamanı türü yerine örneğin çalışma zamanı türünün ( Derivedyani) çağrılacak gerçek yöntem uygulamasını belirlemesidir Base.

Paylaşılan Yöntemler

Değiştirici, Shared bir yöntemin paylaşılan bir yöntem olduğunu gösterir. Paylaşılan yöntem türün belirli bir örneğinde çalışmaz ve türün belirli bir örneği yerine doğrudan bir türden çağrılabilir. Ancak, paylaşılan bir yöntemi nitelemek için bir örneği kullanmak geçerlidir. Paylaşılan bir yöntemde , MyClassveya MyBase öğesine başvurmak Megeçersizdir. Paylaşılan yöntemler Overridable, veya NotOverridableMustOverrideolmayabilir ve yöntemleri geçersiz kılmayabilir. Standart modüllerde ve arabirimlerde tanımlanan yöntemler örtük olarak Shared zaten olduğundan belirtmeyebilirShared.

Değiştiricisi olmayan bir yapıda veya sınıfta bildirilen yöntem Shared bir örnek yöntemidir. Örnek yöntemi, türün belirli bir örneği üzerinde çalışır. Örnek yöntemleri yalnızca bir tür örneği aracılığıyla çağrılabilir ve ifade aracılığıyla Me örneğe başvurabilir.

Aşağıdaki örnekte paylaşılan ve örnek üyelerine erişim kuralları gösterilmektedir:

Class Test
    Private x As Integer
    Private Shared y As Integer

    Sub F()
        x = 1 ' Ok, same as Me.x = 1.
        y = 1 ' Ok, same as Test.y = 1.
    End Sub

    Shared Sub G()
        x = 1 ' Error, cannot access Me.x.
        y = 1 ' Ok, same as Test.y = 1.
    End Sub

    Shared Sub Main()
        Dim t As Test = New Test()

        t.x = 1 ' Ok.
        t.y = 1 ' Ok.
        Test.x = 1 ' Error, cannot access instance member through type.
        Test.y = 1 ' Ok.
    End Sub
End Class

Yöntemi F , bir örnek işlevi üyesinde hem örnek üyelerine hem de paylaşılan üyelere erişmek için bir tanımlayıcının kullanılabileceğini gösterir. Yöntemi G , paylaşılan işlev üyesinde bir tanımlayıcı aracılığıyla örnek üyesine erişmenin bir hata olduğunu gösterir. Yöntemi Main , bir üye erişim ifadesinde örnek üyelerine örnekler aracılığıyla erişilmesi gerektiğini, ancak paylaşılan üyelere türler veya örnekler aracılığıyla erişilebileceğini gösterir.

Yöntem Parametreleri

Parametre, bir yöntemin içine ve dışına bilgi geçirmek için kullanılabilecek bir değişkendir. Bir yöntemin parametreleri, virgülle ayrılmış bir veya daha fazla parametreden oluşan yöntemin parametre listesi tarafından bildirilir.

ParameterList
    : Parameter ( Comma Parameter )*
    ;

Parameter
    : Attributes? ParameterModifier* ParameterIdentifier ( 'As' TypeName )?
      ( Equals ConstantExpression )?
    ;

ParameterModifier
    : 'ByVal' | 'ByRef' | 'Optional' | 'ParamArray'
    ;

ParameterIdentifier
    : Identifier IdentifierModifiers
    ;

Bir parametre için tür belirtilmezse ve katı semantikler kullanılırsa, derleme zamanı hatası oluşur. Aksi takdirde, varsayılan tür veya parametrenin tür karakterinin türüdür Object . İzinli semantikler altında bile, bir parametre bir As yan tümce içeriyorsa, tüm parametreler türleri belirtmelidir.

Parametreler sırasıyla , ByRefOptional, ve ParamArraydeğiştiricileri tarafından ByValdeğer, başvuru, isteğe bağlı veya parametre parametreleri olarak belirtilir. belirtmeyen ByRef veya ByVal varsayılan olarak ByValayarlayan bir parametre.

Parametre adlarının kapsamı yöntemin tüm gövdesine göre belirlenmiştir ve her zaman genel olarak erişilebilir. Yöntem çağrısı, parametrelerin bu çağrıya özgü bir kopyasını oluşturur ve çağrının bağımsız değişken listesi yeni oluşturulan parametrelere değerler veya değişken başvuruları atar. Dış yöntem bildirimlerinin ve temsilci bildirimlerinin gövdesi olmadığından, parametre listelerinde yinelenen parametre adlarına izin verilir, ancak önerilmez.

Tanımlayıcının ardından null atanabilir ad değiştiricisi ? , null atanabilir olduğunu belirtmek için dizi adı değiştiricileri ve bunun bir dizi olduğunu belirtmek için dizi adı değiştiricileri tarafından takip edilebilir. Bunlar birleştirilebilir, örneğin "ByVal x?() As Integer". Açık dizi sınırlarını kullanmasına izin verilmez; ayrıca, null atanabilir ad değiştiricisi varsa bir As yan tümcesi bulunmalıdır.

Değer Parametreleri

Açık değiştirici ile birByVal değer parametresi bildirilir. ByVal Değiştirici kullanılırsa, ByRef değiştirici belirtilmeyebilir. Bir değer parametresi, parametrenin ait olduğu üyenin çağrılanmasıyla ortaya çıkar ve çağırmada verilen bağımsız değişkenin değeriyle başlatılır. Üyenin döndürülmesiyle bir değer parametresi yok olur.

Bir yöntemin bir değer parametresine yeni değerler atamasına izin verilir. Bu tür atamalar yalnızca değer parametresiyle temsil edilen yerel depolama konumunu etkiler; yöntemi çağırmada verilen gerçek bağımsız değişken üzerinde hiçbir etkisi yoktur.

Bir bağımsız değişkenin değeri bir yönteme geçirildiğinde ve parametre değişiklikleri özgün bağımsız değişkeni etkilemediğinde değer parametresi kullanılır. Değer parametresi, karşılık gelen bağımsız değişkenin değişkeninden ayrı olan kendi değişkenine başvurur. Bu değişken, karşılık gelen bağımsız değişkenin değeri kopyalanarak başlatılır. Aşağıdaki örnekte adlı pdeğer parametresine sahip bir yöntem F gösterilmektedir:

Module Test
    Sub F(p As Integer)
        Console.WriteLine("p = " & p)
        p += 1
    End Sub 

    Sub Main()
        Dim a As Integer = 1

        Console.WriteLine("pre: a = " & a)
        F(a)
        Console.WriteLine("post: a = " & a)
    End Sub
End Module

Değer parametresi p değiştirilse bile örnek aşağıdaki çıkışı oluşturur:

pre: a = 1
p = 1
post: a = 1

Başvuru Parametreleri

Başvuru parametresi, değiştirici ile bildirilen bir ByRef parametredir. ByRef Değiştirici belirtilirse, ByVal değiştirici kullanılamayabilir. Başvuru parametresi yeni bir depolama konumu oluşturmaz. Bunun yerine, başvuru parametresi yöntem veya oluşturucu çağırmasında bağımsız değişken olarak verilen değişkeni temsil eder. Kavramsal olarak, başvuru parametresinin değeri her zaman temel alınan değişkenle aynıdır.

Başvuru parametreleri, diğer ad olarak veya kopyalama geri kopyalama yoluyla iki modda çalışır.

Takma. Bir başvuru parametresi, parametre çağıran tarafından sağlanan bağımsız değişken için diğer ad olarak hareket ettiğinde kullanılır. Başvuru parametresi bir değişken tanımlamaz, bunun yerine karşılık gelen bağımsız değişkenin değişkenine başvurur. Bir başvuru parametresinin değişiklikleri doğrudan ve ilgili bağımsız değişkeni hemen etkiler. Aşağıdaki örnekte iki başvuru parametresi olan bir yöntem Swap gösterilmektedir:

Module Test
    Sub Swap(ByRef a As Integer, ByRef b As Integer)
        Dim t As Integer = a
        a = b
        b = t
    End Sub 

    Sub Main()
        Dim x As Integer = 1
        Dim y As Integer = 2

        Console.WriteLine("pre: x = " & x & ", y = " & y)
        Swap(x, y)
        Console.WriteLine("post: x = " & x & ", y = " & y)
    End Sub 
End Module

Programın çıktısı:

pre: x = 1, y = 2
post: x = 2, y = 1

sınıfında yöntemini Swap çağırmak için öğesini a temsil eder x, ve b temsil edery.Main Bu nedenle, çağrı x ve y değerlerini değiştirme etkisine sahiptir.

Başvuru parametrelerini alan bir yöntemde, birden çok adın aynı depolama konumunu temsil etmek mümkündür:

Module Test
    Private s As String

    Sub F(ByRef a As String, ByRef b As String)
        s = "One"
        a = "Two"
        b = "Three"
    End Sub

    Sub G()
        F(s, s)
    End Sub
End Module

Örnekte içindeki yönteminin FG çağrılması hem hem de ba için bir başvuru s geçirir. Bu nedenle, bu çağrı için , ave b adları saynı depolama konumuna başvurur ve üç atamanın tümü örnek değişkenini sdeğiştirir.

Kopyalama geri kopyalama. Başvuru parametresine geçirilen değişkenin türü başvuru parametresinin türüyle uyumlu değilse veya değişken olmayan (örneğin, bir özellik) bir başvuru parametresine bağımsız değişken olarak geçirilirse veya çağrı geç bağlıysa, geçici bir değişken ayrılır ve başvuru parametresine geçirilir. yöntemi çağrılmadan önce geçirilen değer bu geçici değişkene kopyalanır ve yöntem döndürdüğünde özgün değişkene (varsa ve yazılabilirse) geri kopyalanır. Bu nedenle, bir başvuru parametresi geçirilmekte olan değişkenin tam depolamasına yönelik bir başvuru içermeyebilir ve başvuru parametresinde yapılan değişiklikler yöntemden çıkana kadar değişkene yansıtılamayabilir. Örneğin:

Class Base
End Class

Class Derived
    Inherits Base
End Class

Module Test
    Sub F(ByRef b As Base)
        b = New Base()
    End Sub

    Property G() As Base
        Get
        End Get
        Set
        End Set
    End Property

    Sub Main()
        Dim d As Derived

        F(G)   ' OK.
        F(d)   ' Throws System.InvalidCastException after F returns.
    End Sub
End Module

öğesinin ilk çağrılması Fdurumunda geçici bir değişken oluşturulur ve özelliğin G değeri kendisine atanır ve içine Fgeçirilir. 'den Fdöndürülen geçici değişkendeki değer özelliğine Ggeri atanır. İkinci durumda, başka bir geçici değişken oluşturulur ve değeri d bu değişkene atanır ve içine Fgeçirilir. 'den Fdönerken, geçici değişkendeki değer değişkeninin Derivedtürüne geri döndürülerek öğesine atanır d. Geri geçirilen değer olarak değiştirilemediğinden Derived, çalışma zamanında bir özel durum oluşturulur.

İsteğe Bağlı Parametreler

değiştirici ile Optional isteğe bağlı bir parametre bildirilir. Resmi parametre listesindeki isteğe bağlı bir parametreyi izleyen parametreler de isteğe bağlı olmalıdır; aşağıdaki parametrelerde değiştiricinin Optional belirtilememesi derleme zamanı hatasını tetikler. Boş değer atanabilir veya boş değer atanamayan T türde T? isteğe bağlı bir parametre, bağımsız değişken belirtilmezse varsayılan değer olarak kullanılacak bir sabit ifade e belirtmelidir. Object türünde değerlendirilirse eNothingparametre türünün varsayılan değeri parametre için varsayılan değer olarak kullanılır. Aksi takdirde, CType(e, T) sabit bir ifade olmalıdır ve parametre için varsayılan olarak alınır.

İsteğe bağlı parametreler, bir parametredeki başlatıcının geçerli olduğu tek durumdur. Başlatma her zaman çağrı ifadesinin bir parçası olarak yapılır, yöntem gövdesinin içinde değil.

Module Test
    Sub F(x As Integer, Optional y As Integer = 20)
        Console.WriteLine("x = " & x & ", y = " & y)
    End Sub

    Sub Main()
        F(10)
        F(30,40)
    End Sub
End Module

Programın çıktısı:

x = 10, y = 20
x = 30, y = 40

İsteğe bağlı parametreler temsilci veya olay bildirimlerinde veya lambda ifadelerinde belirtilmeyebilir.

ParamArray Parametreleri

ParamArray parametreleri değiştirici ile ParamArray bildirilir. ParamArray Değiştirici varsa, ByVal değiştirici belirtilmelidir ve değiştiriciyi ParamArray başka hiçbir parametre kullanamaz. Parametrenin ParamArray türü tek boyutlu bir dizi olmalı ve parametre listesindeki son parametre olmalıdır.

ParamArray Parametresi, türünün belirsiz sayıda parametresini ParamArraytemsil eder. Yöntemin kendi içinde, bir ParamArray parametre bildirilen türü olarak değerlendirilir ve özel semantiği yoktur. Bir ParamArray parametre, türündeki boş bir tek boyutlu dizi ParamArrayvarsayılan değeriyle örtük olarak isteğe bağlıdır.

A ParamArray , bir yöntem çağrısında bağımsız değişkenlerin iki yoldan biriyle belirtilmesine izin verir:

  • için ParamArray verilen bağımsız değişken, türü genişleten bir türün ParamArray tek bir ifadesi olabilir. Bu durumda, ParamArray tam olarak bir değer parametresi gibi davranır.

  • Alternatif olarak, çağırma için sıfır veya daha fazla bağımsız değişken ParamArraybelirtebilir; burada her bağımsız değişken, öğesinin öğe türüne ParamArrayörtük olarak dönüştürülebilir bir tür ifadesidir. Bu durumda çağrı, türün ParamArray bağımsız değişken sayısına karşılık gelen uzunluğu olan bir örneği oluşturur, dizi örneğinin öğelerini verilen bağımsız değişken değerleriyle başlatır ve yeni oluşturulan dizi örneğini gerçek bağımsız değişken olarak kullanır.

Bir çağrıda değişken sayıda bağımsız değişkene izin vermek dışında, aşağıdaki örnekte gösterildiği gibi , ParamArray tam olarak aynı türdeki bir değer parametresine eşdeğerdir.

Module Test
    Sub F(ParamArray args() As Integer)
        Dim i As Integer

        Console.Write("Array contains " & args.Length & " elements:")
        For Each i In args
            Console.Write(" " & i)
        Next i
        Console.WriteLine()
    End Sub

    Sub Main()
        Dim a As Integer() = { 1, 2, 3 }

        F(a)
        F(10, 20, 30, 40)
        F()
    End Sub
End Module

Örnek çıkışı oluşturur

Array contains 3 elements: 1 2 3
Array contains 4 elements: 10 20 30 40
Array contains 0 elements:

F'ın ilk çağrısı, diziyi bir değer parametresi olarak a'ye geçirir. öğesinin F ikinci çağrısı, belirtilen öğe değerleriyle otomatik olarak dört öğeli bir dizi oluşturur ve bu dizi örneğini bir değer parametresi olarak geçirir. Benzer şekilde, üçüncü çağrı F sıfır öğeli bir dizi oluşturur ve bu örneği bir değer parametresi olarak geçirir. İkinci ve üçüncü çağrılar, yazma işlemiyle tam olarak eşdeğerdir:

F(New Integer() {10, 20, 30, 40})
F(New Integer() {})

ParamArray parametreler temsilci veya olay bildirimlerinde belirtilmeyebilir.

Olay İşleme

Yöntemler, örnek veya paylaşılan değişkenlerdeki nesneler tarafından tetiklenen olayları bildirimli olarak işleyebilir. Olayları işlemek için yöntem bildirimi anahtar sözcüğünü Handles belirtir ve bir veya daha fazla olayı listeler.

HandlesClause
    : ( 'Handles' EventHandlesList )?
    ;

EventHandlesList
    : EventMemberSpecifier ( Comma EventMemberSpecifier )*
    ;

EventMemberSpecifier
    : Identifier Period IdentifierOrKeyword
    | 'MyBase' Period IdentifierOrKeyword
    | 'MyClass' Period IdentifierOrKeyword
    | 'Me' Period IdentifierOrKeyword
    ;

Listedeki bir olay Handles noktayla ayrılmış iki tanımlayıcıyla belirtilir:

  • İlk tanımlayıcı, değiştiriciyi veya anahtar sözcüğünü belirten WithEvents içeren türde bir örnek veya MyBaseMyClassMe paylaşılan değişken olmalıdır; aksi takdirde derleme zamanı hatası oluşur. Bu değişken, bu yöntem tarafından işlenen olayları tetikleyecek nesnesini içerir.

  • İkinci tanımlayıcı, ilk tanımlayıcı türünün bir üyesini belirtmelidir. Üye bir olay olmalıdır ve paylaşılabilir. İlk tanımlayıcı için paylaşılan bir değişken belirtilirse, olayın paylaşılması veya hata sonuçları alınması gerekir.

deyimi AddHandler E, AddressOf M de geçerli olacaksa işleyici yöntemi M bir olay için geçerli bir olay E işleyicisi olarak kabul edilir. Ancak bir AddHandler deyiminden farklı olarak, açık olay işleyicileri katı semantiğin kullanılıp kullanılmadığına bakılmaksızın bağımsız değişken içermeyen bir yöntemle bir olayın işlenmesine izin verir:

Option Strict On

Class C1
    Event E(x As Integer)
End Class

Class C2
    withEvents C1 As New C1()

    ' Valid
    Sub M1() Handles C1.E
    End Sub

    Sub M2()
        ' Invalid
        AddHandler C1.E, AddressOf M1
    End Sub
End Class

Tek bir üye birden çok eşleşen olayı işleyebilir ve birden çok yöntem tek bir olayı işleyebilir. Bir yöntemin erişilebilirliğinin olayları işleme yeteneği üzerinde hiçbir etkisi yoktur. Aşağıdaki örnek, bir yöntemin olayları nasıl işleyebileceğini gösterir:

Class Raiser
    Event E1()

    Sub Raise()
        RaiseEvent E1
    End Sub
End Class

Module Test
    WithEvents x As Raiser

    Sub E1Handler() Handles x.E1
        Console.WriteLine("Raised")
    End Sub

    Sub Main()
        x = New Raiser()
        x.Raise()
        x.Raise()
    End Sub
End Module

Bu, şu şekilde yazdırılır:

Raised
Raised

Bir tür, temel türü tarafından sağlanan tüm olay işleyicilerini devralır. Türetilmiş bir tür, temel türlerinden devraldığı olay eşlemelerini hiçbir şekilde değiştiremez, ancak olaya ek işleyiciler ekleyebilir.

Uzantı Metotları

Yöntemler, uzantı yöntemleri kullanılarak tür bildirimi dışından türlere eklenebilir. Uzantı yöntemleri, özniteliklerinin System.Runtime.CompilerServices.ExtensionAttribute uygulandığı yöntemlerdir. Bunlar yalnızca standart modüllerde bildirilebilir ve yöntemin genişletildiği türü belirten en az bir parametreye sahip olmalıdır. Örneğin, aşağıdaki uzantı yöntemi türünü Stringgenişletir:

Imports System.Runtime.CompilerServices

Module StringExtensions
    <Extension> _
    Sub Print(s As String)
        Console.WriteLine(s)
    End Sub
End Module

Not. Visual Basic, uzantı yöntemlerinin standart bir modülde bildirilmesi gerektirse de, C# gibi diğer diller bunların diğer türlerde bildirilmesine izin verebilir. Yöntemler burada özetlenen diğer kuralları izlediği ve içeren tür açık bir genel tür olmadığı ve örneklenemediği sürece, Visual Basic uzantı yöntemlerini tanır.

Bir uzantı yöntemi çağrıldığında, çağrıldığı örnek ilk parametreye geçirilir. İlk parametre veya ParamArrayolarak bildirilemezOptional. Tür parametresi de dahil olmak üzere herhangi bir tür, uzantı yönteminin ilk parametresi olarak görünebilir. Örneğin, aşağıdaki yöntemler türlerini Integer(), uygulayan System.Collections.Generic.IEnumerable(Of T)herhangi bir türü ve herhangi bir türü genişletir:

Imports System.Runtime.CompilerServices

Module Extensions
    <Extension> _
    Sub PrintArray(a() As Integer)
        ...
    End Sub

    <Extension> _
    Sub PrintList(Of T)(a As IEnumerable(Of T))
        ...
    End Sub

    <Extension> _
    Sub Print(Of T)(a As T)
        ...
    End Sub
End Module

Önceki örnekte gösterildiği gibi, arabirimler genişletilebilir. Arabirim uzantısı yöntemleri yönteminin uygulanmasını sağlar, bu nedenle üzerinde uzantı yöntemleri tanımlanmış olan bir arabirimi uygulayan türler yine de yalnızca başlangıçta arabirim tarafından bildirilen üyeleri uygular. Örneğin:

Imports System.Runtime.CompilerServices

Interface IAction
  Sub DoAction()
End Interface

Module IActionExtensions 
    <Extension> _
    Public Sub DoAnotherAction(i As IAction) 
        i.DoAction()
    End Sub
End Module

Class C
  Implements IAction

  Sub DoAction() Implements IAction.DoAction
    ...
  End Sub

  ' ERROR: Cannot implement extension method IAction.DoAnotherAction
  Sub DoAnotherAction() Implements IAction.DoAnotherAction
    ...
  End Sub
End Class

Uzantı yöntemlerinin tür parametrelerinde de tür kısıtlamaları olabilir ve uzantı olmayan genel yöntemlerde olduğu gibi tür bağımsız değişkeni de çıkarılabilir:

Imports System.Runtime.CompilerServices

Module IEnumerableComparableExtensions
    <Extension> _
    Public Function Sort(Of T As IComparable(Of T))(i As IEnumerable(Of T)) _
        As IEnumerable(Of T)
        ...
    End Function
End Module

Uzantı yöntemlerine, genişletilmekte olan tür içindeki örtük örnek ifadeleri aracılığıyla da erişilebilir:

Imports System.Runtime.CompilerServices

Class C1
    Sub M1()
        Me.M2()
        M2()
    End Sub
End Class

Module C1Extensions
    <Extension>
    Sub M2(c As C1)
        ...
    End Sub
End Module

Erişilebilirlik amacıyla, uzantı yöntemleri de bildirdikleri standart modülün üyeleri olarak değerlendirilir; bildirim bağlamları nedeniyle sahip oldukları erişimin ötesine genişlettikleri türün üyelerine ek erişimleri yoktur.

Uzantı yöntemleri yalnızca standart modül yöntemi kapsam dahilinde olduğunda kullanılabilir. Aksi takdirde, özgün tür genişletilmiş gibi görünmez. Örneğin:

Imports System.Runtime.CompilerServices

Class C1
End Class

Namespace N1
    Module C1Extensions
        <Extension> _
        Sub M1(c As C1)
            ...
        End Sub
    End Module
End Namespace

Module Test
    Sub Main()
        Dim c As New C1()

        ' Error: c has no member named "M1"
        c.M1()
    End Sub
End Module

Yalnızca türdeki bir uzantı yönteminin kullanılabilir olduğu bir türe başvurmak yine de derleme zamanı hatası oluşturur.

Uzantı yöntemlerinin, kesin olarak türü belirlenmiş desen gibi üyelerin bağlı olduğu tüm bağlamlarda türün üyesi olarak kabul edildiğini For Each unutmayın. Örneğin:

Imports System.Runtime.CompilerServices

Class C1
End Class

Class C1Enumerator
    ReadOnly Property Current() As C1
        Get
            ...
        End Get
    End Property

    Function MoveNext() As Boolean
        ...
    End Function
End Class

Module C1Extensions
    <Extension> _
    Function GetEnumerator(c As C1) As C1Enumerator
        ...
    End Function
End Module

Module Test
    Sub Main()
        Dim c As New C1()

        ' Valid
        For Each o As Object In c
            ...
        Next o
    End Sub
End Module

Uzantı yöntemlerine başvuran temsilciler de oluşturulabilir. Bu nedenle kod:

Delegate Sub D1()

Module Test
    Sub Main()
        Dim s As String = "Hello, World!"
        Dim d As D1

        d = AddressOf s.Print
        d()
    End Sub
End Module

kabaca eşdeğerdir:

Delegate Sub D1()

Module Test
    Sub Main()
      Dim s As String = "Hello, World!"
      Dim d As D1

      d = CType([Delegate].CreateDelegate(GetType(D1), s, _
                GetType(StringExtensions).GetMethod("Print")), D1)
      d()
    End Sub
End Module

Not. Visual Basic normalde bir örnek yöntemi çağrısına bir denetim ekler ve yöntemin çağrılmakta olduğu örnek ise bir oluşmasına neden System.NullReferenceException olur Nothing. Uzantı yöntemleri söz konusu olduğunda, bu denetimi eklemenin verimli bir yolu yoktur, bu nedenle uzantı yöntemlerinin için Nothingaçıkça denetlemesi gerekir.

Not. Bir değer türü, arabirim olarak yazılan bir ByVal parametreye bağımsız değişken olarak geçirilirken kutulanır. Bu, uzantı yönteminin yan etkilerinin özgün yerine yapının bir kopyası üzerinde çalışacağını gösterir. Dil, bir uzantı yönteminin ilk bağımsız değişkenine hiçbir kısıtlama koysa da, uzantı yöntemlerinin değer türlerini genişletmek için kullanılmaması veya değer türleri genişletilirken yan etkilerin özgün değer üzerinde çalıştığından emin olmak için ilk parametrenin geçirilmesi ByRef önerilir.

Kısmi Yöntemler

Kısmi yöntem, yöntemin gövdesini değil, imzayı belirten bir yöntemdir. Yöntemin gövdesi, büyük olasılıkla türün başka bir kısmi bildiriminde aynı ada ve imzaya sahip başka bir yöntem bildirimi tarafından sağlanabilir. Örneğin:

a.vb:

' Designer generated code
Public Partial Class MyForm
    Private Partial Sub ValidateControls()
    End Sub

    Public Sub New()
        ' Initialize controls
        ...

        ValidateControls()
    End Sub    
End Class

b.vb:

Public Partial Class MyForm
    Public Sub ValidateControls()
        ' Validation logic goes here
        ...
    End Sub
End Class

Bu örnekte, sınıfın MyForm kısmi bildirimi, uygulama olmadan kısmi bir yöntem ValidateControls bildirir. Kısmi bildirimdeki oluşturucu, dosyada hiçbir gövde sağlanmasa bile kısmi yöntemi çağırır. öğesinin MyForm diğer kısmi bildirimi, yönteminin uygulanmasını sağlar.

Gövde sağlanıp sağlanmadığına bakılmaksızın kısmi yöntemler çağrılabilir; hiçbir yöntem gövdesi sağlanmazsa, çağrı yoksayılır. Örneğin:

Public Class C1
    Private Partial Sub M1()
    End Sub

    Public Sub New()
        ' Since no implementation is supplied, this call will not be made.
        M1()
    End Sub
End Class

Yoksayılan kısmi yöntem çağrısına bağımsız değişken olarak geçirilen ifadeler de yoksayılır ve değerlendirilmez. (Not. Bu, kısmi yöntemlerin kullanılmıyorsa hiçbir maliyeti olmadığından kısmi yöntemlerin iki kısmi türde tanımlanan davranışı sağlamanın çok verimli bir yolu olduğu anlamına gelir.)

Kısmi yöntem bildirimi olarak Private bildirilmelidir ve her zaman gövdesinde deyimi olmayan bir alt yordam olmalıdır. Kısmi yöntemler, arabirim yöntemlerini uygulayamaz, ancak gövdelerini sağlayan yöntem uygulayabilir.

Kısmi bir yönteme yalnızca bir yöntem gövde sağlayabilir. Kısmi bir yönteme gövde sağlayan yöntem, kısmi yöntemle aynı imzaya, herhangi bir tür parametresinde aynı kısıtlamalara, aynı bildirim değiştiricilerine ve aynı parametre ve tür parametre adlarına sahip olmalıdır. Kısmi yöntemdeki öznitelikler ve gövdesini sağlayan yöntem, yöntemlerin parametrelerindeki öznitelikler gibi birleştirilir. Benzer şekilde, yöntemlerin işlediği olayların listesi birleştirilir. Örneğin:

Class C1
    Event E1()
    Event E2()

    Private Partial Sub S() Handles Me.E1
    End Sub

    ' Handles both E1 and E2
    Private Sub S() Handles Me.E2
        ...
    End Sub
End Class

Kurucular

Oluşturucular , başlatma üzerinde denetime izin veren özel yöntemlerdir. Program başladıktan sonra veya bir tür örneği oluşturulduğunda çalıştırılırlar. Diğer üyelerin aksine, oluşturucular devralınmış değildir ve türün bildirim alanına bir ad eklemez. Oluşturucular yalnızca nesne oluşturma ifadeleri veya .NET Framework tarafından çağrılabilir; bunlar hiçbir zaman doğrudan çağrılamayabilir.

Not. Oluşturucular, alt yordamların sahip olduğu satır yerleşiminde aynı kısıtlamaya sahiptir. Başlangıç deyimi, end deyimi ve bloğunun tümü mantıksal satırın başında görünmelidir.

ConstructorMemberDeclaration
    : Attributes? ConstructorModifier* 'Sub' 'New'
      ( OpenParenthesis ParameterList? CloseParenthesis )? LineTerminator
      Block?
      'End' 'Sub' StatementTerminator
    ;

ConstructorModifier
    : AccessModifier
    | 'Shared'
    ;

Örnek Oluşturucuları

Örnek oluşturucuları bir türün örneklerini başlatır ve bir örnek oluşturulduğunda .NET Framework tarafından çalıştırılır. Bir oluşturucunun parametre listesi, bir yöntemin parametre listesiyle aynı kurallara tabidir. Örnek oluşturucuları aşırı yüklenmiş olabilir.

Başvuru türlerindeki tüm oluşturucular başka bir oluşturucu çağırmalıdır. Çağırma açıksa, oluşturucu yöntemi gövdesindeki ilk deyim olmalıdır. deyimi, türün örnek oluşturucularından başka birini çağırabilir (örneğin, Me.New(...) veya -- ya MyClass.New(...) da bir yapı değilse, türün temel türünün örnek oluşturucusunu çağırabilir; örneğin, MyBase.New(...). Oluşturucuların kendisini çağırması geçersizdir. Bir oluşturucu başka bir oluşturucuya yapılan çağrıyı atlarsa örtük MyBase.New() olur. Parametresiz temel tür oluşturucu yoksa, derleme zamanı hatası oluşur. Temel Me sınıf oluşturucusunun çağrısından sonra oluşturulacağı düşünülmediğinden, bir oluşturucu çağırma deyimine yönelik parametreler , MyClassveya örtük olarak veya MyBase açıkça başvuramazMe.

Bir oluşturucunun ilk deyimi biçiminde MyBase.New(...)olduğunda, oluşturucu, türünde bildirilen örnek değişkenlerinin değişken başlatıcıları tarafından belirtilen başlatmaları örtük olarak gerçekleştirir. Bu, doğrudan temel tür oluşturucu çağrıldıktan hemen sonra yürütülen atama dizisine karşılık gelir. Bu tür sıralama, örneğe erişimi olan deyimler yürütülmeden önce tüm temel örnek değişkenlerinin değişken başlatıcıları tarafından başlatılmasını sağlar. Örneğin:

Class A
    Protected x As Integer = 1
End Class

Class B
    Inherits A

    Private y As Integer = x

    Public Sub New()
        Console.WriteLine("x = " & x & ", y = " & y)
    End Sub
End Class

New B() örneği Boluşturmak için kullanıldığında aşağıdaki çıkış oluşturulur:

x = 1, y = 1

değerinin y nedeni, 1 değişken başlatıcının temel sınıf oluşturucu çağrıldıktan sonra yürütülmesidir. Değişken başlatıcılar, tür bildiriminde göründükleri metin sırasına göre yürütülür.

Bir tür yalnızca Private oluşturucuları bildirdiğinde, genel olarak diğer türlerin türünden türetmesi veya türün örneklerini oluşturması mümkün değildir; tek özel durum türün içinde iç içe yerleştirilmiş türlerdir. Private oluşturucular genellikle yalnızca Shared üye içeren türlerde kullanılır.

Bir tür örnek oluşturucu bildirimi içermiyorsa, varsayılan bir oluşturucu otomatik olarak sağlanır. Varsayılan oluşturucu doğrudan temel türün parametresiz oluşturucuyu çağırır. Doğrudan taban türü erişilebilir bir parametresiz oluşturucuya sahip değilse, derleme zamanı hatası oluşur. Varsayılan oluşturucu için bildirilen erişim türü, türü MustInheritolmadığı sürece, Public varsayılan oluşturucudurProtected.

Not. Bir türün varsayılan oluşturucusunun varsayılan erişimi MustInherit , sınıfların doğrudan oluşturulamamasıdır ProtectedMustInherit . Bu nedenle, varsayılan oluşturucuyu Publicyapmanın bir anlamı yoktur.

Aşağıdaki örnekte, sınıfı oluşturucu bildirimi içermediğinden varsayılan bir oluşturucu sağlanır:

Class Message
    Dim sender As Object
    Dim text As String
End Class

Bu nedenle, örnek tam olarak aşağıdakine eşdeğerdir:

Class Message
    Dim sender As Object
    Dim text As String

    Sub New()
    End Sub
End Class

Özniteliğiyle Microsoft.VisualBasic.CompilerServices.DesignerGeneratedAttribute işaretlenmiş tasarımcı tarafından oluşturulan bir sınıfa yayılan varsayılan oluşturucular, temel oluşturucuya yapılan çağrıdan sonra varsa yöntemini Sub InitializeComponent()çağırır. (Not. Bu, tasarımcı tarafından oluşturulan dosyalara (WinForms tasarımcısı tarafından oluşturulanlar gibi) tasarımcı dosyasındaki oluşturucuyu atlayarak izin verir. Bu, programcının bunu kendileri belirtmesine olanak tanır(tercih ederse).)

Paylaşılan Oluşturucular

Paylaşılan oluşturucular bir türün paylaşılan değişkenlerini başlatır; bunlar, program yürütülmeye başladıktan sonra ancak türün bir üyesine yapılan başvurulardan önce çalıştırılır. Paylaşılan bir oluşturucu, değiştiricinin Shared örtüldiği standart bir modülde olmadığı sürece değiştiriciyi Shared belirtir.

Örnek oluşturucularından farklı olarak, paylaşılan oluşturucuların örtük genel erişimi vardır, parametresi yoktur ve diğer oluşturucuları çağıramayabilir. Paylaşılan bir oluşturucudaki ilk deyimden önce, paylaşılan oluşturucu, türünde bildirilen paylaşılan değişkenlerin değişken başlatıcıları tarafından belirtilen başlatmaları örtük olarak gerçekleştirir. Bu, oluşturucuya girdikten hemen sonra yürütülen atama dizisine karşılık gelir. Değişken başlatıcıları, tür bildiriminde göründükleri metin sırasına göre yürütülür.

Aşağıdaki örnekte, paylaşılan değişken başlatan paylaşılan oluşturucuya sahip bir sınıf gösterilmektedir Employee :

Imports System.Data

Class Employee
    Private Shared ds As DataSet

    Shared Sub New()
        ds = New DataSet()
    End Sub

    Public Name As String
    Public Salary As Decimal
End Class

Her kapalı genel tür için ayrı bir paylaşılan oluşturucu vardır. Paylaşılan oluşturucu her kapalı tür için tam olarak bir kez yürütülür çünkü, kısıtlamalar aracılığıyla derleme zamanında denetlenemeyen tür parametresinde çalışma zamanı denetimlerini zorunlu kılmak için uygun bir yerdir. Örneğin, aşağıdaki tür, tür parametresinin Integer veya Doubleolmasını zorunlu kılmak için paylaşılan bir oluşturucu kullanır:

Class EnumHolder(Of T)
    Shared Sub New() 
        If Not GetType(T).IsEnum() Then
            Throw New ArgumentException("T must be an enumerated type.")
        End If
    End Sub
End Class

Tam olarak paylaşılan oluşturucular çalıştırıldığında çoğunlukla uygulamaya bağımlıdır, ancak paylaşılan bir oluşturucu açıkça tanımlanırsa çeşitli garantiler sağlanır:

  • Paylaşılan oluşturucular, türündeki herhangi bir statik alana ilk erişimden önce çalıştırılır.

  • Paylaşılan oluşturucular, türündeki herhangi bir statik yöntemin ilk çağrılmasından önce çalıştırılır.

  • Paylaşılan oluşturucular, türü için herhangi bir oluşturucunun ilk çağrılmasından önce çalıştırılır.

Yukarıdaki garantiler, paylaşılan başlatıcılar için örtük olarak bir paylaşılan oluşturucunun oluşturulduğu durumlarda geçerli değildir. Yüklemenin tam sırası ve dolayısıyla paylaşılan oluşturucu yürütme tanımlanmadığından, aşağıdaki örnekteki çıktı kesin değildir:

Module Test
    Sub Main()
        A.F()
        B.F()
    End Sub
End Module

Class A
    Shared Sub New()
        Console.WriteLine("Init A")
    End Sub

    Public Shared Sub F()
        Console.WriteLine("A.F")
    End Sub
End Class

Class B
    Shared Sub New()
        Console.WriteLine("Init B")
    End Sub

    Public Shared Sub F()
        Console.WriteLine("B.F")
    End Sub
End Class

Çıkış aşağıdakilerden biri olabilir:

Init A
A.F
Init B
B.F

veya

Init B
Init A
A.F
B.F

Buna karşılık, aşağıdaki örnek tahmin edilebilir bir çıkış oluşturur. Sınıfın oluşturucusunun Shared , sınıfından A türetilmiş olsa B bile hiçbir zaman yürütülmeyeceğini unutmayın:

Module Test
    Sub Main()
        B.G()
    End Sub
End Module

Class A
    Shared Sub New()
        Console.WriteLine("Init A")
    End Sub
End Class

Class B
    Inherits A

    Shared Sub New()
        Console.WriteLine("Init B")
    End Sub

    Public Shared Sub G()
        Console.WriteLine("B.G")
    End Sub
End Class

Çıktı şudur:

Init B
B.G

Aşağıdaki örnekte olduğu gibi değişken başlatıcılı değişkenlerin varsayılan değer durumlarında gözlemlenmelerine olanak sağlayan Shared döngüsel bağımlılıklar oluşturmak da mümkündür:

Class A
    Public Shared X As Integer = B.Y + 1
End Class

Class B
    Public Shared Y As Integer = A.X + 1

    Shared Sub Main()
        Console.WriteLine("X = " & A.X & ", Y = " & B.Y)
    End Sub
End Class

Bu, çıktıyı üretir:

X = 1, Y = 2

Yöntemini yürütmek Main için sistem önce sınıfını Byükler. sınıfının SharedB oluşturucusunun ilk değerini Yhesaplaması devam eder ve bu da değerine başvurulduğundan özyinelemeli olarak sınıfının A yüklenmesine A.X neden olur. Sırayla Shared sınıfının A oluşturucu, ilk değerini Xhesaplamaya devam eder ve bunu yaptığınızda sıfır olan varsayılan değerini Ygetirir. A.X bu nedenle olarak 1başlatılır. Yükleme A işlemi tamamlanır ve ilk değerinin Yhesaplamasına geri dönülerek sonucu olur 2.

Main Bunun yerine yöntemi sınıfında Abulunsaydı, örnek aşağıdaki çıkışı üretirdi:

X = 2, Y = 1

Değişken başlatıcılarda Shared döngüsel başvurulardan kaçının çünkü bu tür başvuruları içeren sınıfların hangi sırayla yüklendiğini belirlemek genellikle imkansızdır.

Etkinlikler

Olaylar, belirli bir oluşumun kodunu bildirmek için kullanılır. Olay bildirimi, temsilci türünden veya parametre listesinden ve isteğe bağlı Implements yan tümceden oluşan bir tanımlayıcıdan oluşur.

EventMemberDeclaration
    : RegularEventMemberDeclaration
    | CustomEventMemberDeclaration
    ;

RegularEventMemberDeclaration
    : Attributes? EventModifiers* 'Event'
      Identifier ParametersOrType ImplementsClause? StatementTerminator
    ;

InterfaceEventMemberDeclaration
    : Attributes? InterfaceEventModifiers* 'Event'
      Identifier ParametersOrType StatementTerminator
    ;

ParametersOrType
    : ( OpenParenthesis ParameterList? CloseParenthesis )?
    | 'As' NonArrayTypeName
    ;

EventModifiers
    : AccessModifier
    | 'Shadows'
    | 'Shared'
    ;

InterfaceEventModifiers
    : 'Shadows'
    ;

Bir temsilci türü belirtilirse, temsilci türünün dönüş türü olmayabilir. Parametre listesi belirtilirse, veya ParamArray parametreleri içermeyebilirOptional. Parametre türlerinin ve/veya temsilci türünün erişilebilirlik etki alanı, olayın erişilebilirlik etki alanıyla aynı veya üst kümesi olmalıdır. Olaylar değiştirici belirtilerek Shared paylaşılabilir.

Türün bildirim alanına eklenen üye adına ek olarak, olay bildirimi diğer birkaç üyeyi örtük olarak bildirir. adlı Xbir olay verildiğinde, bildirim alanına aşağıdaki üyeler eklenir:

  • Bildirimin biçimi bir yöntem bildirimiyse, adlı XEventHandler iç içe bir temsilci sınıfı tanıtılır. İç içe temsilci sınıfı yöntem bildirimiyle eşleşir ve olayla aynı erişilebilirliğe sahiptir. Parametre listesindeki öznitelikler, temsilci sınıfının parametrelerine uygulanır.

  • Private Temsilci olarak yazılan ve adlı XEventbir örnek değişkeni.

  • adlı ve remove_X adlı add_X iki yöntem çağrılamaz, geçersiz kılınamaz veya aşırı yüklenemez.

Bir tür, yukarıdaki adlardan biriyle eşleşen bir ad bildirmeye çalışırsa, derleme zamanı hatası oluşur ve örtük add_X ve remove_X bildirimler ad bağlama amacıyla yoksayılır. Türetilmiş türlerde gölgelendirmek mümkün olsa da, tanıtılan üyelerden herhangi birini geçersiz kılmak veya aşırı yüklemek mümkün değildir. Örneğin, sınıf bildirimi

Class Raiser
    Public Event Constructed(i As Integer)
End Class

aşağıdaki bildirime eşdeğerdir

Class Raiser
    Public Delegate Sub ConstructedEventHandler(i As Integer)

    Protected ConstructedEvent As ConstructedEventHandler

    Public Sub add_Constructed(d As ConstructedEventHandler)
        ConstructedEvent = _
            CType( _
                [Delegate].Combine(ConstructedEvent, d), _
                    Raiser.ConstructedEventHandler)
    End Sub

    Public Sub remove_Constructed(d As ConstructedEventHandler)
        ConstructedEvent = _
            CType( _
                [Delegate].Remove(ConstructedEvent, d), _
                    Raiser.ConstructedEventHandler)
    End Sub
End Class

Temsilci türü belirtmeden olay bildirmek en basit ve en kısa söz dizimidir, ancak her olay için yeni bir temsilci türü bildirme dezavantajı vardır. Örneğin, aşağıdaki örnekte üç gizli temsilci türü oluşturulur, ancak üç olay da aynı parametre listesine sahiptir:

Public Class Button
    Public Event Click(sender As Object, e As EventArgs)
    Public Event DoubleClick(sender As Object, e As EventArgs)
    Public Event RightClick(sender As Object, e As EventArgs)
End Class

Aşağıdaki örnekte, olaylar yalnızca aynı temsilciyi EventHandlerkullanır:

Public Delegate Sub EventHandler(sender As Object, e As EventArgs)

Public Class Button
    Public Event Click As EventHandler
    Public Event DoubleClick As EventHandler
    Public Event RightClick As EventHandler
End Class

Olaylar iki yoldan biriyle işlenebilir: statik veya dinamik. Olayları statik olarak işlemek daha basittir ve yalnızca değişken WithEvents ve yan Handles tümce gerektirir. Aşağıdaki örnekte sınıfıForm1, nesnesinin Buttonolayını Click statik olarak işler:

Public Class Form1
    Public WithEvents Button1 As New Button()

    Public Sub Button1_Click(sender As Object, e As EventArgs) _
           Handles Button1.Click
        Console.WriteLine("Button1 was clicked!")
    End Sub
End Class

Olayların dinamik olarak işlenmesi daha karmaşıktır çünkü olayın kodda açıkça bağlanması ve bağlantısının kesilmesi gerekir. deyimi AddHandler bir olay için bir işleyici ekler ve deyimi RemoveHandler bir olayın işleyicisini kaldırır. Sonraki örnekte, 'nin olayı için Button1olay işleyicisi olarak ekleyen Button1_Click bir sınıf Form1 gösterilmektedirClick:

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

yönteminde Disconnect, olay işleyicisi kaldırılır.

Özel Olaylar

Önceki bölümde açıklandığı gibi, olay bildirimleri örtük olarak bir alan, bir add_ yöntem ve olay işleyicilerini izlemek için kullanılan bir remove_ yöntemi tanımlar. Ancak bazı durumlarda, olay işleyicilerini izlemek için özel kod sağlamak istenebilir. Örneğin, bir sınıf yalnızca birkaçının işlendiği kırk olay tanımlarsa, her olayın işleyicilerini izlemek için kırk alan yerine karma tablo kullanmak daha verimli olabilir. Özel olaylar ve remove_X yöntemlerinin add_X açıkça tanımlanmasını sağlar ve bu da olay işleyicileri için özel depolama sağlar.

Özel olaylar, anahtar sözcüğün anahtar sözcüğünden Custom önce Event olması gerektiği dışında, temsilci türü belirten olayların bildirilmesiyle aynı şekilde bildirilir. Özel olay bildirimi üç bildirim içerir: bildirim AddHandler , RemoveHandler bildirim ve bildirim RaiseEvent . Bildirimlerin hiçbirinde değiştiricisi yoktur, ancak öznitelikleri olabilir.

CustomEventMemberDeclaration
    : Attributes? EventModifiers* 'Custom' 'Event'
      Identifier 'As' TypeName ImplementsClause? StatementTerminator
      EventAccessorDeclaration+
      'End' 'Event' StatementTerminator
    ;

EventAccessorDeclaration
    : AddHandlerDeclaration
    | RemoveHandlerDeclaration
    | RaiseEventDeclaration
    ;

AddHandlerDeclaration
    : Attributes? 'AddHandler'
      OpenParenthesis ParameterList CloseParenthesis LineTerminator
      Block?
      'End' 'AddHandler' StatementTerminator
    ;

RemoveHandlerDeclaration
    : Attributes? 'RemoveHandler'
      OpenParenthesis ParameterList CloseParenthesis LineTerminator
      Block?
      'End' 'RemoveHandler' StatementTerminator
    ;

RaiseEventDeclaration
    : Attributes? 'RaiseEvent'
      OpenParenthesis ParameterList CloseParenthesis LineTerminator
      Block?
      'End' 'RaiseEvent' StatementTerminator
    ;

Örneğin:

Class Test
    Private Handlers As EventHandler

    Public Custom Event TestEvent As EventHandler
        AddHandler(value As EventHandler)
            Handlers = CType([Delegate].Combine(Handlers, value), _
                EventHandler)
        End AddHandler

        RemoveHandler(value as EventHandler)
            Handlers = CType([Delegate].Remove(Handlers, value), _
                EventHandler)
        End RemoveHandler

        RaiseEvent(sender As Object, e As EventArgs)
            Dim TempHandlers As EventHandler = Handlers

            If TempHandlers IsNot Nothing Then
                TempHandlers(sender, e)
            End If
        End RaiseEvent
    End Event
End Class

AddHandler ve RemoveHandler bildirimi, olayın temsilci türünde olması gereken bir ByVal parametre alır. Bir AddHandler veya RemoveHandler deyimi yürütülürse (veya yan Handles tümcesi bir olayı otomatik olarak işlerse), ilgili bildirim çağrılır. Bildirim, RaiseEvent olay temsilcisiyle aynı parametreleri alır ve bir RaiseEvent deyim yürütürken çağrılır. Tüm bildirimler sağlanmalıdır ve alt yordam olarak kabul edilir.

ve RemoveHandlerRaiseEvent bildirimlerininAddHandler, alt yordamlarla aynı satır yerleştirme kısıtlaması olduğuna dikkat edin. Başlangıç deyimi, end deyimi ve bloğunun tümü mantıksal satırın başında görünmelidir.

Türün bildirim alanına eklenen üye adına ek olarak, özel bir olay bildirimi diğer birkaç üyeyi örtük olarak bildirir. adlı Xbir olay verildiğinde, bildirim alanına aşağıdaki üyeler eklenir:

  • bildirimine AddHandler karşılık gelen adlı add_Xbir yöntem.

  • bildirimine RemoveHandler karşılık gelen adlı remove_Xbir yöntem.

  • bildirimine RaiseEvent karşılık gelen adlı fire_Xbir yöntem.

Bir tür, yukarıdaki adlardan biriyle eşleşen bir ad bildirmeye çalışırsa, derleme zamanı hatası oluşur ve örtük bildirimlerin tümü ad bağlama amacıyla yoksayılır. Türetilmiş türlerde gölgelendirmek mümkün olsa da, tanıtılan üyelerden herhangi birini geçersiz kılmak veya aşırı yüklemek mümkün değildir.

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

WinRT derlemelerinde özel olaylar

Microsoft Visual Basic 11.0 itibarıyla, ile /target:winmdobjderlenen veya böyle bir dosyadaki bir arabirimde bildirilen ve sonra başka bir yerde uygulanan bir dosyada bildirilen olaylar biraz farklı ele alınır.

  • Winmd'yi oluşturmak için kullanılan dış araçlar genellikle yalnızca veya System.TypedEventHandle(Of T, U)gibi System.EventHandler(Of T) belirli temsilci türlerine izin verir ve başkalarına izin vermez.

  • Alanın XEvent türü System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable(Of T) vardır; burada T temsilci türüdür.

  • AddHandler erişimcisi bir System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokendöndürür ve RemoveHandler erişimcisi aynı türde tek bir parametre alır.

Bu tür özel bir olaya örnek olarak aşağıda verilmiştir.

Imports System.Runtime.InteropServices.WindowsRuntime

Public NotInheritable Class ClassInWinMD
    Private XEvent As EventRegistrationTokenTable(Of EventHandler(Of Integer))

    Public Custom Event X As EventHandler(Of Integer)
        AddHandler(handler As EventHandler(Of Integer))
            Return EventRegistrationTokenTable(Of EventHandler(Of Integer)).
                   GetOrCreateEventRegistrationTokenTable(XEvent).
                   AddEventHandler(handler)
        End AddHandler

        RemoveHandler(token As EventRegistrationToken)
            EventRegistrationTokenTable(Of EventHandler(Of Integer)).
                GetOrCreateEventRegistrationTokenTable(XEvent).
                RemoveEventHandler(token)
        End RemoveHandler

        RaiseEvent(sender As Object, i As Integer)
            Dim table = EventRegistrationTokenTable(Of EventHandler(Of Integer)).
                GetOrCreateEventRegistrationTokenTable(XEvent).
                InvocationList
            If table IsNot Nothing Then table(sender, i)
        End RaiseEvent
    End Event
End Class

Sabitler

Sabit, bir türün üyesi olan sabit bir değerdir.

ConstantMemberDeclaration
    : Attributes? ConstantModifier* 'Const' ConstantDeclarators StatementTerminator
    ;

ConstantModifier
    : AccessModifier
    | 'Shadows'
    ;

ConstantDeclarators
    : ConstantDeclarator ( Comma ConstantDeclarator )*
    ;

ConstantDeclarator
    : Identifier ( 'As' TypeName )? Equals ConstantExpression StatementTerminator
    ;

Sabitler örtük olarak paylaşılır. Bildirimde bir As yan tümce varsa, yan tümcesi bildirim tarafından tanıtılan üyenin türünü belirtir. Tür atlanırsa, sabitin türü çıkarılır. Sabitin türü yalnızca ilkel bir tür veya Objectolabilir. Sabit olarak Object yazıldıysa ve tür karakteri yoksa, sabitin gerçek türü sabit ifadenin türü olur. Aksi takdirde, sabitin türü sabitin tür karakterinin türüdür.

Aşağıdaki örnekte iki ortak sabiti olan adlı Constants bir sınıf gösterilmektedir:

Class Constants
    Public Const A As Integer = 1
    Public Const B As Integer = A + 1
End Class

Aşağıdaki örnekte olduğu gibi ve değerlerini yazdıran sabitlere Constants.AConstants.Bsınıfı üzerinden erişilebilir.

Module Test
    Sub Main()
        Console.WriteLine(Constants.A & ", " & Constants.B)
    End Sub 
End Module

Birden çok sabiti bildiren sabit bir bildirim, tek sabitlerin birden çok bildirimine eşdeğerdir. Aşağıdaki örnek, bir bildirim deyiminde üç sabit bildirir.

Class A
    Protected Const x As Integer = 1, y As Long = 2, z As Short = 3
End Class

Bu bildirim aşağıdakiyle eşdeğerdir:

Class A
    Protected Const x As Integer = 1
    Protected Const y As Long = 2
    Protected Const z As Short = 3
End Class

Sabitin türündeki erişilebilirlik etki alanı, sabitin erişilebilirlik etki alanının üst kümesiyle aynı veya üst kümesi olmalıdır. Sabit ifade, sabitin türüne veya sabitin türüne örtük olarak dönüştürülebilir bir türe sahip bir değer vermelidir. Sabit ifade döngüsel olmayabilir; yani, bir sabit kendi açısından tanımlanamaz.

Derleyici, sabit bildirimleri otomatik olarak uygun sırada değerlendirir. Aşağıdaki örnekte, derleyici önce sırasıyla Z10, 11 ve 12 değerlerini üreten , ve son Xolarak değerini değerlendirirY.

Class A
    Public Const X As Integer = B.Z + 1
    Public Const Y As Integer = 10
End Class

Class B
    Public Const Z As Integer = A.Y + 1
End Class

Sabit bir değer için sembolik ad istendiğinde, ancak değerin türüne sabit bir bildirimde izin verilmezse veya değer bir sabit ifade tarafından derleme zamanında hesaplanamazsa, bunun yerine salt okunur bir değişken kullanılabilir.

Örnek ve Paylaşılan Değişkenler

Örnek veya paylaşılan değişken, bilgileri depolayan bir türün üyesidir.

VariableMemberDeclaration
    : Attributes? VariableModifier+ VariableDeclarators StatementTerminator
    ;

VariableModifier
    : AccessModifier
    | 'Shadows'
    | 'Shared'
    | 'ReadOnly'
    | 'WithEvents'
    | 'Dim'
    ;

VariableDeclarators
    : VariableDeclarator ( Comma VariableDeclarator )*
    ;

VariableDeclarator
    : VariableIdentifiers 'As' ObjectCreationExpression
    | VariableIdentifiers ( 'As' TypeName )? ( Equals Expression )?
    ;

VariableIdentifiers
    : VariableIdentifier ( Comma VariableIdentifier )*
    ;

VariableIdentifier
    : Identifier IdentifierModifiers
    ;

Değiştirici Dim belirtilmezse değiştirici belirtilmelidir, ancak aksi takdirde atlanabilir. Tek bir değişken bildirimi birden çok değişken bildirimcisi içerebilir; her değişken bildirimcisi yeni bir örnek veya paylaşılan üye ekler.

Başlatıcı belirtilirse, değişken bildirimcisi tarafından yalnızca bir örnek veya paylaşılan değişken bildirilebilir:

Class Test
    Dim a, b, c, d As Integer = 10  ' Invalid: multiple initialization
End Class

Bu kısıtlama nesne başlatıcılar için geçerli değildir:

Class Test
    Dim a, b, c, d As New Collection() ' OK
End Class

Değiştirici ile Shared bildirilen değişken , paylaşılan bir değişkendir. Paylaşılan değişken, oluşturulan türün örnek sayısından bağımsız olarak tam olarak bir depolama konumu tanımlar. Paylaşılan değişken, bir program yürütülmeye başladığında ortaya çıkar ve program sonlandırıldığında mevcut olmaz.

Paylaşılan değişken yalnızca belirli bir kapalı genel türün örnekleri arasında paylaşılır. Örneğin, program:

Class C(Of V) 
    Shared InstanceCount As Integer = 0

    Public Sub New()  
        InstanceCount += 1 
    End Sub

    Public Shared ReadOnly Property Count() As Integer 
        Get
            Return InstanceCount
        End Get
    End Property
End Class

Class Application 
    Shared Sub Main() 
        Dim x1 As New C(Of Integer)()
        Console.WriteLine(C(Of Integer).Count)

        Dim x2 As New C(Of Double)() 
        Console.WriteLine(C(Of Integer).Count)

        Dim x3 As New C(Of Integer)() 
        Console.WriteLine(C(Of Integer).Count)
    End Sub
End Class

Yazdırılır:

1
1
2

Değiştirici olmadan Shared bildirilen bir değişkene örnek değişkeni adı verilir. Sınıfın her örneği, sınıfın tüm örnek değişkenlerinin ayrı bir kopyasını içerir. Bir başvuru türünün örnek değişkeni, bu türün yeni bir örneği oluşturulduğunda ortaya çıkar ve söz konusu örneğe başvuru olmadığında ve Finalize yöntem yürütülürken yok olur. Bir değer türünün örnek değişkeni, ait olduğu değişkenle tam olarak aynı yaşam süresine sahiptir. Başka bir deyişle, bir değer türündeki bir değişken ortaya çıktığında veya var olmaktan çıktığında, değer türünün örnek değişkeni de var olur.

Bildirimci bir As yan tümce içeriyorsa, yan tümcesi bildirimi tarafından tanıtılan üyelerin türünü belirtir. Tür atlanırsa ve katı semantikler kullanılıyorsa, derleme zamanı hatası oluşur. Aksi takdirde, üyelerin türü örtük olarak Object veya üyelerin tür karakterinin türüdür.

Not. Söz diziminde belirsizlik yoktur: Bir bildirimci bir türü atlarsa, her zaman aşağıdaki bildirimcinin türünü kullanır.

Örneğin erişilebilirlik etki alanı veya paylaşılan değişkenin türü veya dizi öğesi türü, örneğin veya paylaşılan değişkenin erişilebilirlik etki alanının üst kümesiyle aynı olmalıdır.

Aşağıdaki örnekte , greenPartve bluePartadlı redPartiç örnek değişkenleri olan bir Color sınıf gösterilmektedir:

Class Color
    Friend redPart As Short
    Friend bluePart As Short
    Friend greenPart As Short

    Public Sub New(red As Short, blue As Short, green As Short)
        redPart = red
        bluePart = blue
        greenPart = green
    End Sub
End Class

değişkenleri Read-Only

Bir örnek veya paylaşılan değişken bildirimi bir ReadOnly değiştirici içerdiğinde, bildirimi tarafından tanıtılan değişkenlere atamalar yalnızca bildirimin bir parçası olarak veya aynı sınıftaki bir oluşturucuda gerçekleşebilir. Özellikle, salt okunur bir örneğe veya paylaşılan değişkene atamalara yalnızca aşağıdaki durumlarda izin verilir:

  • Örneği veya paylaşılan değişkeni tanıtır değişken bildiriminde (bildirime bir değişken başlatıcısı ekleyerek).

  • Bir örnek değişkeni için, değişken bildirimini içeren sınıfının örnek oluşturucularında. Örnek değişkenine yalnızca nitelenmemiş bir şekilde veya aracılığıyla MeMyClasserişilebilir.

  • Paylaşılan değişken için, paylaşılan değişken bildirimini içeren sınıfın paylaşılan oluşturucusunda.

Paylaşılan salt okunur değişken, sabit bir değer için sembolik bir ad istendiğinde, ancak değerin türüne sabit bir bildirimde izin verilmediğinde veya değerin derleme zamanında sabit bir ifade tarafından hesaplanamadığında yararlıdır.

Bu tür ilk uygulamaya örnek olarak, renk paylaşılan değişkenlerin diğer programlar tarafından değiştirilmesini önlemek için bildirildiği ReadOnly örnek aşağıda verilmiştir:

Class Color
    Friend redPart As Short
    Friend bluePart As Short
    Friend greenPart As Short

    Public Sub New(red As Short, blue As Short, green As Short)
        redPart = red
        bluePart = blue
        greenPart = green
    End Sub 

    Public Shared ReadOnly Red As Color = New Color(&HFF, 0, 0)
    Public Shared ReadOnly Blue As Color = New Color(0, &HFF, 0)
    Public Shared ReadOnly Green As Color = New Color(0, 0, &HFF)
    Public Shared ReadOnly White As Color = New Color(&HFF, &HFF, &HFF)
End Class

Sabitler ve salt okunur paylaşılan değişkenler farklı semantiklere sahiptir. bir ifade bir sabite başvurduğunda, derleme zamanında sabitin değeri elde edilir, ancak bir ifade salt okunur paylaşılan değişkene başvurduğunda, paylaşılan değişkenin değeri çalışma zamanına kadar alınmaz. İki ayrı programdan oluşan aşağıdaki uygulamayı göz önünde bulundurun.

file1.vb:

Namespace Program1
    Public Class Utils
        Public Shared ReadOnly X As Integer = 1
    End Class
End Namespace

file2.vb:

Namespace Program2
    Module Test
        Sub Main()
            Console.WriteLine(Program1.Utils.X)
        End Sub
    End Module
End Namespace

Ad alanları Program1 ve Program2 ayrı olarak derlenen iki programı belirtir. Değişken Program1.Utils.X olarak Shared ReadOnlybildirildiğinden, deyiminin Console.WriteLine değer çıkışı derleme zamanında bilinmez, bunun yerine çalışma zamanında elde edilir. Bu nedenle, değeri X değiştirilir ve Program1 yeniden derlenirse, Console.WriteLine deyimi yeniden derlenmese Program2 bile yeni değerin çıkışını verir. Ancak, sabit olsaydıX, değeri X derlendiği sırada Program2 elde edilirdi ve yeniden derlenene kadar Program2 içindeki Program1 değişikliklerden etkilenmeden kalırdı.

WithEvents Değişkenleri

Bir tür, örneğinden veya paylaşılan değişkenlerinden biri tarafından tetiklenen bazı olay kümesini, değiştiriciyle olayları tetikleyen örneği veya paylaşılan değişkeni bildirerek işlediğini WithEvents bildirebilir. Örneğin:

Class Raiser
    Public Event E1()

    Public Sub Raise()
        RaiseEvent E1
    End Sub
End Class

Module Test
    Private WithEvents x As Raiser

    Private Sub E1Handler() Handles x.E1
        Console.WriteLine("Raised")
    End Sub

    Public Sub Main()
        x = New Raiser()
    End Sub
End Module

Bu örnekte yöntemiE1Handler, örnek değişkeninde xdepolanan türün Raiser örneği tarafından tetiklenen olayı E1 işler.

Değiştirici, WithEvents değişkenin öndeki alt çizgiyle yeniden adlandırılıp yerine olay kancası oluşturan aynı ada sahip bir özelliğin değiştirilmesine neden olur. Örneğin, değişkenin adı olarak Fyeniden adlandırılır _F ve bir özellik F örtük olarak bildirilir. Değişkenin yeni adıyla başka bir bildirim arasında bir çakışma varsa, derleme zamanı hatası bildirilir. Değişkene uygulanan tüm öznitelikler yeniden adlandırılan değişkene taşınır.

Bir WithEvents bildirim tarafından oluşturulan örtük özellik, ilgili olay işleyicilerini bağlamayı ve kancayı kaldırmayı üstlenir. Değişkene bir değer atandığında, özelliği ilk olarak şu anda değişkende olan örnekteki olay için yöntemini çağırır remove (varsa mevcut olay işleyicisinin kancasını kaldırma). Daha sonra atama yapılır ve özelliği değişkenindeki add yeni örnekteki olay için yöntemini çağırır (yeni olay işleyicisini bağlama). Aşağıdaki kod, standart modül Testiçin yukarıdaki koda eşdeğerdir:

Module Test
    Private _x As Raiser

    Public Property x() As Raiser
        Get
            Return _x
        End Get

        Set (Value As Raiser)
            ' Unhook any existing handlers.
            If _x IsNot Nothing Then
                RemoveHandler _x.E1, AddressOf E1Handler
            End If

            ' Change value.
            _x = Value

            ' Hook-up new handlers.
            If _x IsNot Nothing Then
                AddHandler _x.E1, AddressOf E1Handler
            End If
        End Set
    End Property

    Sub E1Handler()
        Console.WriteLine("Raised")
    End Sub

    Sub Main()
        x = New Raiser()
    End Sub
End Module

Bir örneği veya paylaşılan değişkeni, değişken bir yapı olarak yazılmış gibi WithEvents bildirmek geçerli değildir. Ayrıca, WithEvents bir yapıda belirtilemez ve WithEventsReadOnly birleştirilemez.

Değişken Başlatıcıları

Sınıflardaki örnek ve paylaşılan değişken bildirimleri ve yapılardaki örnek değişkeni bildirimleri (ancak paylaşılan değişken bildirimleri değil) değişken başlatıcıları içerebilir. Değişkenler için Shared değişken başlatıcıları, program başladıktan sonra ancak değişkene ilk kez başvurulmadan önce Shared yürütülen atama deyimlerine karşılık gelir. Örneğin değişkenleri için değişken başlatıcılar, sınıfın bir örneği oluşturulduğunda yürütülen atama deyimlerine karşılık gelir. Yapıların parametresiz oluşturucuları değiştirilemediğinden örnek değişkeni başlatıcıları olamaz.

Aşağıdaki örneği göz önünde bulundurun:

Class Test
    Public Shared x As Double = Math.Sqrt(2.0)
    Public i As Integer = 100
    Public s As String = "Hello"
End Class

Module TestModule
    Sub Main()
        Dim a As New Test()

        Console.WriteLine("x = " & Test.x & ", i = " & a.i & ", s = " & a.s)
    End Sub
End Module

Örnek aşağıdaki çıkışı oluşturur:

x = 1.4142135623731, i = 100, s = Hello

Bir atama x , sınıf yüklendiğinde gerçekleşir ve sınıfın yeni bir örneği oluşturulduğunda ve atamaları is gerçekleşir.

Değişken başlatıcılarını türün oluşturucusunun bloğuna otomatik olarak eklenen atama deyimleri olarak düşünmek yararlıdır. Aşağıdaki örnekte birkaç örnek değişkeni başlatıcısı yer alır.

Class A
    Private x As Integer = 1
    Private y As Integer = -1
    Private count As Integer

    Public Sub New()
        count = 0
    End Sub

    Public Sub New(n As Integer)
        count = n
    End Sub
End Class

Class B
    Inherits A

    Private sqrt2 As Double = Math.Sqrt(2.0)
    Private items As ArrayList = New ArrayList(100)
    Private max As Integer

    Public Sub New()
        Me.New(100)
        items.Add("default")
    End Sub

    Public Sub New(n As Integer)
        MyBase.New(n - 1)
        max = n
    End Sub
End Class

Örnek, aşağıda gösterilen koda karşılık gelir ve burada her açıklama otomatik olarak eklenen bir deyimi gösterir.

Class A
    Private x, y, count As Integer

    Public Sub New()
        MyBase.New ' Invoke object() constructor.
        x = 1 ' This is a variable initializer.
        y = -1 ' This is a variable initializer.
        count = 0
    End Sub

    Public Sub New(n As Integer)
        MyBase.New ' Invoke object() constructor. 
        x = 1 ' This is a variable initializer.
        y = - 1 ' This is a variable initializer.
        count = n
    End Sub
End Class

Class B
    Inherits A

    Private sqrt2 As Double
    Private items As ArrayList
    Private max As Integer

    Public Sub New()
        Me.New(100) 
        items.Add("default")
    End Sub

    Public Sub New(n As Integer)
        MyBase.New(n - 1) 
        sqrt2 = Math.Sqrt(2.0) ' This is a variable initializer.
        items = New ArrayList(100) ' This is a variable initializer.
        max = n
    End Sub
End Class

Tüm değişkenler, herhangi bir değişken başlatıcı yürütülmeden önce türünün varsayılan değerine başlatılır. Örneğin:

Class Test
    Public Shared b As Boolean
    Public i As Integer
End Class

Module TestModule
    Sub Main()
        Dim t As New Test()
        Console.WriteLine("b = " & Test.b & ", i = " & t.i)
    End Sub
End Module

b Sınıf yüklendiğinde varsayılan değerine otomatik olarak başlatıldığından ve i sınıfın bir örneği oluşturulduğunda otomatik olarak varsayılan değerine başlatıldığından, yukarıdaki kod aşağıdaki çıkışı oluşturur:

b = False, i = 0

Her değişken başlatıcı, değişkenin türüne veya değişkenin türüne örtük olarak dönüştürülebilir bir türe sahip bir değer vermelidir. Değişken başlatıcı döngüsel olabilir veya ondan sonra başlatılacak bir değişkene başvurabilir; bu durumda başvurulan değişkenin değeri başlatıcının amaçları için varsayılan değeridir. Böyle bir başlatıcı şüpheli bir değerdir.

Değişken başlatıcıların üç biçimi vardır: normal başlatıcılar, dizi boyutu başlatıcıları ve nesne başlatıcıları. İlk iki form, tür adını izleyen bir eşittir işaretinden sonra görünür, ikinci ikisi bildirimin bir parçasıdır. Belirli bir bildirimde yalnızca bir başlatıcı biçimi kullanılabilir.

Normal Başlatıcılar

Normal başlatıcı, değişkenin türüne örtük olarak dönüştürülebilen bir ifadedir. Tür adını izleyen bir eşittir işaretinden sonra görünür ve değer olarak sınıflandırılması gerekir. Örneğin:

Module Test
    Dim x As Integer = 10
    Dim y As Integer = 20

    Sub Main()
        Console.WriteLine("x = " & x & ", y = " & y)
    End Sub
End Module

Bu program çıktıyı üretir:

x = 10, y = 20

Değişken bildiriminde normal başlatıcı varsa, aynı anda yalnızca tek bir değişken bildirilebilir. Örneğin:

Module Test
    Sub Main()
        ' OK, only one variable declared at a time.
        Dim x As Integer = 10, y As Integer = 20

        ' Error: Can't initialize multiple variables at once.
        Dim a, b As Integer = 10
    End Sub
End Module

Nesne Başlatıcıları

Nesne başlatıcı, tür adının yerine bir nesne oluşturma ifadesi kullanılarak belirtilir. Nesne başlatıcı, nesne oluşturma ifadesinin sonucunu değişkene atayan normal başlatıcıya eşdeğerdir. Öyle

Module TestModule
    Sub Main()
        Dim x As New Test(10)
    End Sub
End Module

ile eşdeğer

Module TestModule
    Sub Main()
        Dim x As Test = New Test(10)
    End Sub
End Module

Bir nesne başlatıcıdaki parantez her zaman oluşturucunun bağımsız değişken listesi olarak yorumlanır ve hiçbir zaman dizi türü değiştiricileri olarak yorumlanır. Nesne başlatıcısı olan değişken adının dizi türü değiştiricisi veya null atanabilir tür değiştiricisi olamaz.

Array-Size Başlatıcıları

Dizi boyutu başlatıcısı, ifadelerle belirtilen boyut üst sınırları kümesi veren değişkenin adında bir değiştiricidir.

ArraySizeInitializationModifier
    : OpenParenthesis BoundList CloseParenthesis ArrayTypeModifiers?
    ;

BoundList
    : Bound ( Comma Bound )*
    ;

Bound
    : Expression
    | '0' 'To' Expression
    ;

Üst sınır ifadeleri değer olarak sınıflandırılmalı ve örtük olarak dönüştürülebilir Integerolmalıdır. Üst sınır kümesi, verilen üst sınırlarla dizi oluşturma ifadesinin değişken başlatıcısına eşdeğerdir. Dizi türünün boyut sayısı, dizi boyutu başlatıcısından çıkarılır. Öyle

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

ile eşdeğer

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

Tüm üst sınırların -1'e eşit veya bundan büyük olması ve tüm boyutların belirtilen üst sınıra sahip olması gerekir. Başlatılmakta olan dizinin öğe türü bir dizi türüyse, dizi türü değiştiricileri dizi boyutu başlatıcısının sağındakine gider. Örneğin:

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

türü, ilk boyutta ve 0..10 ikinci boyutta sınırları 0..5 olan bir diziye başlatılan üç boyutlu dizilerinden Integeroluşan iki boyutlu bir dizi olan bir yerel değişken x bildirir. Türü dizi dizisi olan bir değişkenin öğelerini başlatmak için dizi boyutu başlatıcısı kullanmak mümkün değildir.

Dizi boyutu başlatıcısı olan bir değişken bildiriminin türünde bir dizi türü değiştiricisi veya normal başlatıcısı olamaz.

System.MarshalByRefObject Sınıfları

sınıfından System.MarshalByRefObject türetilen sınıflar, kopyalama (değere göre) yerine proxy'ler (başvuruya göre) kullanılarak bağlam sınırları boyunca sıralanır. Bu, böyle bir sınıfın örneğinin gerçek bir örnek olmadığı, bunun yerine yalnızca bağlam sınırı boyunca değişken erişimlerini ve yöntem çağrılarını sıralayan bir saplama olabileceği anlamına gelir.

Sonuç olarak, bu tür sınıflarda tanımlanan değişkenlerin depolama konumuna başvuru oluşturmak mümkün değildir. Bu, türetilen System.MarshalByRefObject sınıflar olarak yazılan değişkenlerin başvuru parametrelerine geçirilemeyeceği ve değer türü olarak yazılan değişkenlerin yöntemlerine ve değişkenlerine erişilemeyeceği anlamına gelir. Bunun yerine, Visual Basic bu tür sınıflarda tanımlanan değişkenleri özellikmiş gibi (kısıtlamalar özelliklerde aynı olduğundan) ele almaktadır.

Bu kuralın tek bir özel durumu vardır: ile örtük veya açıkça nitelenen Me bir üye yukarıdaki kısıtlamalardan muaftır, çünkü Me her zaman proxy değil gerçek bir nesne olduğu garanti edilir.

Özellikler

Özellikler değişkenlerin doğal bir uzantısıdır; her ikisi de ilişkili türlere sahip adlandırılmış üyelerdir ve değişkenlere ve özelliklere erişme söz dizimi aynıdır. Ancak, değişkenlerin aksine, özellikler depolama konumlarını göstermez. Bunun yerine, özelliklerin değerlerini okumak veya yazmak için yürütülecek deyimleri belirten erişimcileri vardır.

Özellikler, özellik bildirimleriyle tanımlanır. Özellik bildiriminin ilk bölümü alan bildirimine benzer. İkinci bölüm bir Get aksesuar ve/veya bir Set aksesuar içerir.

PropertyMemberDeclaration
    : RegularPropertyMemberDeclaration
    | MustOverridePropertyMemberDeclaration
    | AutoPropertyMemberDeclaration
    ;

PropertySignature
    : 'Property'
      Identifier ( OpenParenthesis ParameterList? CloseParenthesis )?
      ( 'As' Attributes? TypeName )?
    ;

RegularPropertyMemberDeclaration
    : Attributes? PropertyModifier* PropertySignature
      ImplementsClause? LineTerminator
      PropertyAccessorDeclaration+
      'End' 'Property' StatementTerminator
    ;

MustOverridePropertyMemberDeclaration
    : Attributes? MustOverridePropertyModifier+ PropertySignature
      ImplementsClause? StatementTerminator
    ;

AutoPropertyMemberDeclaration
    : Attributes? AutoPropertyModifier* 'Property' Identifier
      ( OpenParenthesis ParameterList? CloseParenthesis )?
      ( 'As' Attributes? TypeName )? ( Equals Expression )?
      ImplementsClause? LineTerminator
    | Attributes? AutoPropertyModifier* 'Property' Identifier
      ( OpenParenthesis ParameterList? CloseParenthesis )?
      'As' Attributes? 'New'
      ( NonArrayTypeName ( OpenParenthesis ArgumentList? CloseParenthesis )? )?
      ObjectCreationExpressionInitializer?
      ImplementsClause? LineTerminator
    ;

InterfacePropertyMemberDeclaration
    : Attributes? InterfacePropertyModifier* PropertySignature StatementTerminator
    ;

AutoPropertyModifier
    : AccessModifier
    | 'Shadows'
    | 'Shared'
    | 'Overridable'
    | 'NotOverridable'
    | 'Overrides'
    | 'Overloads'
    ;

PropertyModifier
    : AutoPropertyModifier
    | 'Default'
    | 'ReadOnly'
    | 'WriteOnly'
    | 'Iterator'
    ;

MustOverridePropertyModifier
    : PropertyModifier
    | 'MustOverride'
    ;

InterfacePropertyModifier
    : 'Shadows'
    | 'Overloads'
    | 'Default'
    | 'ReadOnly'
    | 'WriteOnly'
    ;

PropertyAccessorDeclaration
    : PropertyGetDeclaration
    | PropertySetDeclaration
    ;

Aşağıdaki örnekte sınıfı Button bir Caption özellik tanımlar.

Public Class Button
    Private captionValue As String

    Public Property Caption() As String
        Get
            Return captionValue
        End Get

        Set (Value As String)
            captionValue = value
            Repaint()
        End Set
    End Property

    ...
End Class

Yukarıdaki sınıfa Button bağlı olarak, özelliğin kullanımına Caption bir örnek aşağıda verilmiştir:

Dim okButton As Button = New Button()

okButton.Caption = "OK" ' Invokes Set accessor.
Dim s As String = okButton.Caption ' Invokes Get accessor.

Burada, Set erişimci özelliğine bir değer atanarak çağrılır ve Get erişimci bir ifadedeki özelliğe başvurarak çağrılır.

Bir özellik için tür belirtilmezse ve katı semantikler kullanılıyorsa, derleme zamanı hatası oluşur; aksi takdirde özelliğin türü örtük olarak Object veya özelliğin tür karakterinin türüdür. Özellik bildirimi, özelliğin değerini alan bir Get erişimci, özelliğin değerini depolayan bir Set erişimci veya her ikisini birden içerebilir. Bir özellik örtük olarak yöntemleri bildirdiğinden, bir özellik bir yöntemle aynı değiştiricilerle bildirilebilir. Özellik bir arabirimde tanımlanırsa veya değiştirici ile MustOverride tanımlanırsa, özellik gövdesi ve End yapısı atlanmalıdır; aksi takdirde derleme zamanı hatası oluşur.

Dizin parametresi listesi özelliğin imzasını oluşturur, bu nedenle özellikler dizin parametrelerinde aşırı yüklenebilir ancak özelliğin türüne göre aşırı yüklenmeyebilir. Dizin parametresi listesi normal bir yöntemle aynıdır. Ancak, parametrelerin hiçbiri değiştirici ile ByRef değiştirilemez ve hiçbiri adlandırılamaz Value (erişimcideki Set örtük değer parametresi için ayrılmıştır).

Bir özellik aşağıdaki gibi bildirilebilir:

  • Özelliği hiçbir özellik türü değiştirici belirtirse, özelliğin hem erişimci Get hem de erişimci Set olması gerekir. Özelliğin okuma-yazma özelliği olduğu söylenir.

  • özelliği değiştiriciyi ReadOnly belirtiyorsa, özelliğin bir Get erişimcisi olmalıdır ve bir Set erişimcisi olmayabilir. Özelliğin salt okunur özellik olduğu söylenir. Salt okunur özelliğin bir atamanın hedefi olması derleme zamanı hatasıdır.

  • özelliği değiştiriciyi WriteOnly belirtiyorsa, özelliğin bir Set erişimcisi olmalıdır ve bir Get erişimcisi olmayabilir. Özelliğin salt yazma özelliği olduğu söylenir. Bir atamanın hedefi veya bir yöntemin bağımsız değişkeni olarak dışında bir ifadedeki salt yazma özelliğine başvurmak derleme zamanı hatasıdır.

Get Bir özelliğin ve Set erişimcileri ayrı üyeler değildir ve bir özelliğin erişimcilerini ayrı olarak bildirmek mümkün değildir. Aşağıdaki örnek tek bir okuma-yazma özelliği bildirmez. Bunun yerine, biri salt okunur, diğeri salt yazma olan aynı ada sahip iki özellik bildirir:

Class A
    Private nameValue As String

    ' Error, contains a duplicate member name.
    Public ReadOnly Property Name() As String 
        Get
            Return nameValue
        End Get
    End Property

    ' Error, contains a duplicate member name.
    Public WriteOnly Property Name() As String 
        Set (Value As String)
            nameValue = value
        End Set
    End Property
End Class

Aynı sınıfta bildirilen iki üye aynı ada sahip olamayacağından, örnek derleme zamanı hatasına neden olur.

Varsayılan olarak, bir özelliğin Get ve Set erişimcilerinin erişilebilirliği özelliğin erişilebilirliğiyle aynıdır. Ancak ve GetSet erişimcileri ayrıca özelliğinden ayrı olarak erişilebilirliği de belirtebilir. Bu durumda, bir erişimcinin erişilebilirliği özelliğin erişilebilirliğinden daha kısıtlayıcı olmalıdır ve yalnızca bir erişimci özelliğinden farklı bir erişilebilirlik düzeyine sahip olabilir. Erişim türleri aşağıdaki gibi daha fazla veya daha az kısıtlayıcı olarak kabul edilir:

  • Private, , Protected FriendProtectedveya Frienddeğerinden Publicdaha kısıtlayıcıdır.

  • Friendveya Publicdeğerinden Protected Friend daha kısıtlayıcıdır.

  • Protectedveya Publicdeğerinden Protected Friend daha kısıtlayıcıdır.

  • Protected Friend değerinden Publicdaha kısıtlayıcıdır.

Bir özelliğin erişimcilerinden biri erişilebilirken diğeri erişilmediğinde, özellik salt okunur veya salt okunur olarak değerlendirilir. Örneğin:

Class A
    Public Property P() As Integer
        Get
            ...
        End Get

        Private Set (Value As Integer)
            ...
        End Set
    End Property
End Class

Module Test
    Sub Main()
        Dim a As A = New A()

        ' Error: A.P is read-only in this context.
        a.P = 10
    End Sub
End Module

Türetilmiş bir tür bir özelliği gölgelediğinde, türetilmiş özellik hem okuma hem de yazma bakımından gölgeli özelliği gizler. Aşağıdaki örnekte, P içindeki B özelliği hem okuma hem de yazma bakımından P özelliğini A gizler:

Class A
    Public WriteOnly Property P() As Integer
        Set (Value As Integer)
        End Set
    End Property
End Class

Class B
    Inherits A

    Public Shadows ReadOnly Property P() As Integer
       Get
       End Get
    End Property
End Class

Module Test
    Sub Main()
        Dim x As B = New B

        B.P = 10     ' Error, B.P is read-only.
    End Sub
End Module

Dönüş türünün veya parametre türlerinin erişilebilirlik etki alanı, özelliğin erişilebilirlik etki alanının üst kümesiyle aynı veya üst kümesi olmalıdır. Bir özellik yalnızca bir Set erişimciye ve bir erişimciye Get sahip olabilir.

Bildirim ve çağırma söz dizimindeki farklar dışında, Overridable, NotOverridable, Overrides, MustOverrideve MustInherit özellikleri tam olarak , NotOverridable, Overrides, MustOverrideve MustInherit yöntemleri gibi Overridabledavranır. Bir özellik geçersiz kılındığında, geçersiz kılma özelliği aynı türde olmalıdır (okuma-yazma, salt okunur, salt yazma). Bir Overridable özellik erişimci Private içeremez.

Aşağıdaki örnekte X salt okunur bir Overridable özellik, YOverridable bir okuma-yazma özelliği ve Z bir okuma-yazma özelliğidir MustOverride .

MustInherit Class A
    Private _y As Integer

    Public Overridable ReadOnly Property X() As Integer
        Get
            Return 0
        End Get
    End Property

    Public Overridable Property Y() As Integer
        Get
            Return _y
         End Get
        Set (Value As Integer)
            _y = value
        End Set
    End Property

    Public MustOverride Property Z() As Integer
End Class

olduğundan ZMustOverride, içeren sınıfı A bildirilmelidir MustInherit.

Buna karşılık, sınıfından türetilen bir sınıf A aşağıda gösterilmiştir:

Class B
    Inherits A

    Private _z As Integer

    Public Overrides ReadOnly Property X() As Integer
        Get
            Return MyBase.X + 1
        End Get
    End Property

    Public Overrides Property Y() As Integer
        Get
            Return MyBase.Y
        End Get
        Set (Value As Integer)
            If value < 0 Then
                MyBase.Y = 0
            Else
                MyBase.Y = Value
            End If
        End Set
    End Property

    Public Overrides Property Z() As Integer
        Get
            Return _z
        End Get
        Set (Value As Integer)
            _z = Value
        End Set
    End Property
End Class

Burada, özelliklerin XYbildirimleri ve Z temel özellikleri geçersiz kılar. Her özellik bildirimi, ilgili devralınan özelliğin erişilebilirlik değiştiricileri, türü ve adıyla tam olarak eşleşir. Özelliğin GetX erişimcisi ve Set özelliğin Y erişimcisi devralınan MyBase özelliklere erişmek için anahtar sözcüğünü kullanır. özelliğinin Z bildirimi özelliği geçersiz kılar MustOverride ; bu nedenle sınıfında bekleyen MustOverride üye Byoktur ve B normal bir sınıf olmasına izin verilir.

Özellikler, kaynağın başlatılmasını ilk başvurulana kadar geciktirmek için kullanılabilir. Örneğin:

Imports System.IO

Public Class ConsoleStreams
    Private Shared reader As TextReader
    Private Shared writer As TextWriter
    Private Shared errors As TextWriter

    Public Shared ReadOnly Property [In]() As TextReader
        Get
            If reader Is Nothing Then
                reader = Console.In
            End If
            Return reader
        End Get
    End Property

    Public Shared ReadOnly Property Out() As TextWriter
        Get
            If writer Is Nothing Then
                writer = Console.Out
            End If
            Return writer
        End Get
    End Property

    Public Shared ReadOnly Property [Error]() As TextWriter
        Get
            If errors Is Nothing Then
                errors = Console.Error
            End If
            Return errors
        End Get
    End Property
End Class

ConsoleStreams sınıfı, sırasıyla standart girişi, çıkışı ve hata cihazlarını temsil eden üç özellik içerir: In, Out ve Error. Bu üyeler özellik olarak gösterilerek, ConsoleStreams sınıf gerçekten kullanılana kadar başlatmalarını geciktirebilir. Örneğin, ilk kez içinde olduğu gibi ConsoleStreams.Out.WriteLine("hello, world")özelliğine Out başvurarak çıktı cihazının temeli TextWriter başlatılır. Ancak uygulama ve Error özelliklerine In başvuru yapmazsa, bu cihazlar için hiçbir nesne oluşturulmaz.

Erişimci Bildirimlerini Alma

Erişimci Get (getter) bir özellik Get bildirimi kullanılarak bildirilir. Özellik Get bildirimi, anahtar sözcüğünden Get ve ardından bir deyim bloğundan oluşur. adlı Pbir özellik verildiğinde, erişimci Get bildirimi, özelliğiyle aynı değiştiricilere, türe ve parametre listesine sahip bir get_P yöntemi örtük olarak bildirir. Tür bu ada sahip bir bildirim içeriyorsa, derleme zamanı hatasıyla sonuçlanır, ancak örtük bildirim ad bağlama amacıyla yoksayılır.

Erişimci gövdesinin Get bildirim alanında, özelliğiyle aynı ada sahip örtük olarak bildirilen özel bir yerel değişken, özelliğin dönüş değerini temsil eder. 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 ifadeyi bekleyen bir bağlamda kullanılıyorsa, ad yerel değişken yerine işleve çözümleniyor demektir. Örneğin:

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

Parantezlerin kullanılması belirsiz durumlara neden olabilir (örneğin, türü tek boyutlu bir dizi olan bir özelliğin nerede F olduğu gibiF(1)). Tüm belirsiz durumlarda, ad yerel değişken yerine özelliğine çözümür. Örneğin:

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

Denetim akışı erişimci gövdesinden Get ayrıldığında, yerel değişkenin değeri çağırma ifadesine geri geçirilir. Bir Get erişimciyi çağırmak kavramsal olarak bir değişkenin değerini okumakla eşdeğer olduğundan, aşağıdaki örnekte gösterildiği gibi erişimcilerin gözlemlenebilir yan etkilere sahip olması kötü programlama stili Get olarak kabul edilir:

Class Counter
    Private Value As Integer

    Public ReadOnly Property NextValue() As Integer
        Get
            Value += 1
            Return Value
        End Get
    End Property
End Class

özelliğinin NextValue değeri, özelliğin daha önce kaç kez erişildiğine bağlıdır. Bu nedenle, özelliğine erişmek gözlemlenebilir bir yan etki oluşturur ve bunun yerine özelliğin bir yöntem olarak uygulanması gerekir.

Erişimciler için Get "yan etkisi yok" kuralı, erişimcilerin her zaman yalnızca değişkenlerde depolanan değerleri döndürmek için yazılması gerektiği anlamına gelmez Get . Aslında, Get erişimciler genellikle birden çok değişkene erişerek veya yöntemleri çağırarak bir özelliğin değerini hesaplar. Ancak, düzgün tasarlanmış Get bir erişimci nesnenin durumunda gözlemlenebilir değişikliklere neden olan hiçbir eylem gerçekleştirmez.

Not. Get erişimciler, alt yordamların sahip olduğu satır yerleşiminde aynı kısıtlamaya sahiptir. Başlangıç deyimi, end deyimi ve bloğunun tümü mantıksal satırın başında görünmelidir.

PropertyGetDeclaration
    : Attributes? AccessModifier? 'Get' LineTerminator
      Block?
      'End' 'Get' StatementTerminator
    ;

Erişimci Bildirimlerini Ayarla

Erişimci Set (ayarlayıcı) bir özellik kümesi bildirimi kullanılarak bildirilir. Özellik kümesi bildirimi anahtar sözcüğünden Set, isteğe bağlı parametre listesinden ve deyim bloğundan oluşur. adlı Pbir özellik verildiğinde, bir setter bildirimi, özelliğiyle aynı değiştiricilere ve parametre listesine sahip ada set_P sahip bir yöntemi örtük olarak bildirir. Tür bu ada sahip bir bildirim içeriyorsa, derleme zamanı hatasıyla sonuçlanır, ancak örtük bildirim ad bağlama amacıyla yoksayılır.

Parametre listesi belirtilirse, bir üyesi olmalı, bu üyenin dışında ByValdeğiştiricisi olmamalıdır ve türü özelliğin türüyle aynı olmalıdır. parametresi, ayarlanan özellik değerini temsil eder. parametresi atlanırsa, adlı Value bir parametre örtük olarak bildirilir.

Not. Set erişimciler, alt yordamların sahip olduğu satır yerleşiminde aynı kısıtlamaya sahiptir. Başlangıç deyimi, end deyimi ve bloğunun tümü mantıksal satırın başında görünmelidir.

PropertySetDeclaration
    : Attributes? AccessModifier? 'Set'
      ( OpenParenthesis ParameterList? CloseParenthesis )? LineTerminator
      Block?
      'End' 'Set' StatementTerminator
    ;

Varsayılan Özellikler

Değiştiriciyi Default belirten bir özellik , varsayılan özellik olarak adlandırılır. Özelliklere izin veren her tür, arabirimler de dahil olmak üzere varsayılan bir özelliğe sahip olabilir. Varsayılan özelliğe, örneği özelliğin adıyla nitelemek zorunda kalmadan başvurulabilir. Bu nedenle, bir sınıf ver

Class Test
    Public Default ReadOnly Property Item(i As Integer) As Integer
        Get
            Return i
        End Get
    End Property
End Class

kod

Module TestModule
    Sub Main()
        Dim x As Test = New Test()
        Dim y As Integer

        y = x(10)
    End Sub
End Module

ile eşdeğer

Module TestModule
    Sub Main()
        Dim x As Test = New Test()
        Dim y As Integer

        y = x.Item(10)
    End Sub
End Module

Bir özellik bildirildikten Defaultsonra, devralma hiyerarşisinde bu ada aşırı yüklenen tüm özellikler, bildirilmiş Default olsun veya olmasın varsayılan özellik haline gelir. Temel sınıf başka bir adla varsayılan bir özellik bildirdiğinde türetilmiş bir sınıfta bir özellik Default bildirmek veya Overridesgibi Shadows başka değiştiriciler gerektirmez. Bunun nedeni, varsayılan özelliğin kimliği veya imzası olmaması ve bu nedenle gölgelenememesi veya aşırı yüklenememesidir. Örneğin:

Class Base
    Public ReadOnly Default Property Item(i As Integer) As Integer
        Get
            Console.WriteLine("Base = " & i)
        End Get
    End Property
End Class

Class Derived
    Inherits Base

    ' This hides Item, but does not change the default property.
    Public Shadows ReadOnly Property Item(i As Integer) As Integer
        Get
            Console.WriteLine("Derived = " & i)
        End Get
    End Property
End Class

Class MoreDerived
    Inherits Derived

    ' This declares a new default property, but not Item.
    ' This does not need to be declared Shadows
    Public ReadOnly Default Property Value(i As Integer) As Integer
        Get
            Console.WriteLine("MoreDerived = " & i)
        End Get
    End Property
End Class

Module Test
    Sub Main()
        Dim x As MoreDerived = New MoreDerived()
        Dim y As Integer
        Dim z As Derived = x

        y = x(10)        ' Calls MoreDerived.Value.
        y = x.Item(10)   ' Calls Derived.Item
        y = z(10)        ' Calls Base.Item
    End Sub
End Module

Bu program çıktıyı oluşturur:

MoreDerived = 10
Derived = 10
Base = 10

Bir tür içinde bildirilen tüm varsayılan özelliklerin aynı ada sahip olması ve netlik için değiştiriciyi belirtmesi Default gerekir. Dizin parametresi olmayan bir varsayılan özellik, içeren sınıfın örnekleri atanırken belirsiz bir duruma neden olacağından, varsayılan özelliklerin dizin parametreleri olmalıdır. Ayrıca, belirli bir ad üzerinde aşırı yüklenmiş bir özellik değiştirici içeriyorsa Default , bu ad üzerinde aşırı yüklenen tüm özelliklerin bunu belirtmesi gerekir. Varsayılan özellikler olmayabilir Sharedve özelliğin en az bir erişimcisi olmamalıdır Private.

Otomatik Uygulanan Özellikler

Bir özellik herhangi bir erişimcinin bildirimini atlarsa, özellik bir arabirimde bildirilmediği veya bildirilmediği MustOverridesürece özelliğin bir uygulaması otomatik olarak sağlanır. Yalnızca bağımsız değişken içermeyen okuma/yazma özellikleri otomatik olarak uygulanabilir; aksi takdirde derleme zamanı hatası oluşur.

Otomatik olarak uygulanan bir özellik, başka bir özelliği xgeçersiz kılsa bile, özelliğiyle aynı türe sahip özel bir yerel değişken _x tanıtır. Yerel değişkenin adıyla başka bir bildirim arasında bir çakışma varsa, derleme zamanı hatası bildirilir. Otomatik olarak uygulanan özelliğin Get erişimcisi yerel değerini ve yerel değerini ayarlayan özelliğin Set erişimcisini döndürür. Örneğin, bildirimi:

Public Property x() As Integer

kabaca eşdeğerdir:

Private _x As Integer
Public Property x() As Integer
    Get
        Return _x
    End Get
    Set (value As Integer)
        _x = value
    End Set
End Property

Değişken bildirimlerinde olduğu gibi, otomatik olarak uygulanan bir özellik başlatıcı içerebilir. Örneğin:

Public Property x() As Integer = 10
Public Shared Property y() As New Customer() With { .Name = "Bob" }

Not. Otomatik olarak uygulanan bir özellik başlatıldığında, temel alan değil özelliği aracılığıyla başlatılır. Bu nedenle geçersiz kılma özellikleri, gerekirse başlatma işleminin önünü kesebilir.

Dizi başlatıcılarına otomatik olarak uygulanan özelliklerde izin verilir, ancak dizi sınırlarını açıkça belirtmenin bir yolu yoktur. Örneğin:

' Valid
Property x As Integer() = {1, 2, 3}
Property y As Integer(,) = {{1, 2, 3}, {12, 13, 14}, {11, 10, 9}}

' Invalid
Property x4(5) As Short

Yineleyici Özellikleri

Yineleyici özelliği, değiştiricisi Iterator olan bir özelliktir. Aynı nedenle bir yineleyici yöntemi (Bölüm Yineleyici Yöntemleri) kullanılır. Bu yöntem, deyimi tarafından kullanılabilecek bir dizi oluşturmanın For Each kullanışlı bir yoludur. Yineleyici Get özelliğinin erişimcisi, yineleyici yöntemiyle aynı şekilde yorumlanır.

Yineleyici özelliğinin açık Get bir erişimcisi olmalı ve türü , veya IEnumerableveya ya da IEnumerator(Of T)IEnumerable(Of T) bazı Tiçin olmalıdırIEnumerator.

Yineleyici özelliğine bir örnek aşağıda verilmiştir:

Class Family
    Property Daughters As New List(Of String) From {"Beth", "Diane"}
    Property Sons As New List(Of String) From {"Abe", "Carl"}

    ReadOnly Iterator Property Children As IEnumerable(Of String)
        Get
            For Each name In Daughters : Yield name : Next
            For Each name In Sons : Yield name : Next
        End Get
    End Property
End Class

Module Module1
    Sub Main()
        Dim x As New Family
        For Each c In x.Children
            Console.WriteLine(c) ' prints Beth, Diane, Abe, Carl
        Next
    End Sub
End Module

Operatörler

İşleçler , içeren sınıf için mevcut bir Visual Basic işlecinin anlamını tanımlayan yöntemlerdir. işleci bir ifadedeki sınıfına uygulandığında, işleç sınıfında tanımlanan işleç yöntemine yönelik bir çağrı olarak derlenmiş. Bir sınıf için işleç tanımlama, işleci aşırı yükleme olarak da bilinir.

OperatorDeclaration
    : Attributes? OperatorModifier* 'Operator' OverloadableOperator
      OpenParenthesis ParameterList CloseParenthesis
      ( 'As' Attributes? TypeName )? LineTerminator
      Block?
      'End' 'Operator' StatementTerminator
    ;

OperatorModifier
    : 'Public' | 'Shared' | 'Overloads' | 'Shadows' | 'Widening' | 'Narrowing'
    ;

OverloadableOperator
    : '+' | '-' | '*' | '/' | '\\' | '&' | 'Like' | 'Mod' | 'And' | 'Or' | 'Xor'
    | '^' | '<' '<' | '>' '>' | '=' | '<' '>' | '>' | '<' | '>' '=' | '<' '='
    | 'Not' | 'IsTrue' | 'IsFalse' | 'CType'
    ;

Zaten var olan bir işleci aşırı yüklemek mümkün değildir; uygulamada, bu öncelikli olarak dönüştürme işleçleri için geçerlidir. Örneğin, türetilmiş bir sınıftan temel sınıfa dönüştürmeyi aşırı yüklemek mümkün değildir:

Class Base
End Class

Class Derived
    ' Cannot redefine conversion from Derived to Base,
    ' conversion will be ignored.
    Public Shared Widening Operator CType(s As Derived) As Base
        ...
    End Operator
End Class

İşleçler, sözcüğün sağduyusunda da aşırı yüklenebilir:

Class Base
    Public Shared Widening Operator CType(b As Base) As Integer
        ...
    End Operator

    Public Shared Narrowing Operator CType(i As Integer) As Base
        ...
    End Operator
End Class

İşleç bildirimleri, içeren türün bildirim alanına açıkça ad eklemez; ancak , "op_" karakterleriyle başlayan ilgili bir yöntemi örtük olarak bildirir. Aşağıdaki bölümlerde, her işleçle ilgili yöntem adları listelemektedir.

Tanımlanabilir üç işleç sınıfı vardır: birli işleçler, ikili işleçler ve dönüştürme işleçleri. Tüm işleç bildirimleri belirli kısıtlamaları paylaşır:

  • İşleç bildirimleri her zaman ve SharedolmalıdırPublic. Değiştiricinin Public varsayılacağı bağlamlarda değiştirici atlanabilir.

  • Bir işlecin parametreleri veya OptionalParamArrayolarak bildirilemezByRef.

  • İşlenenlerden en az birinin türü veya dönüş değeri işlecini içeren tür olmalıdır.

  • İşleçler için tanımlanmış işlev dönüş değişkeni yok. Bu nedenle, Return bir işleç gövdesinden değer döndürmek için deyimi kullanılmalıdır.

Bu kısıtlamaların tek özel durumu, null atanabilir değer türleri için geçerlidir. Null atanabilir değer türleri gerçek bir tür tanımına sahip olmadığından, bir değer türü türün null atanabilir sürümü için kullanıcı tanımlı işleçler bildirebilir. Bir türün belirli bir kullanıcı tanımlı işleci bildirip bildiremeyeceğini belirlerken, ? değiştiriciler önce geçerlilik denetimi amacıyla bildirimde yer alan tüm türlerden bırakılır. Bu gevşeme, ve işleçlerinin IsTrue dönüş türü için geçerli değildir; yine de döndürmelidirBoolean, değilBoolean?.IsFalse

Bir işlecin önceliği ve ilişkilendirilebilirliği bir işleç bildirimi tarafından değiştirilemez.

Not. İşleçler, alt yordamların sahip olduğu satır yerleşiminde aynı kısıtlamaya sahiptir. Başlangıç deyimi, end deyimi ve bloğunun tümü mantıksal satırın başında görünmelidir.

Tekli İşleçler

Aşağıdaki birli işleçler aşırı yüklenebilir:

  • Birli artı işleci + (karşılık gelen yöntem: op_UnaryPlus)

  • Birli eksi işleci - (karşılık gelen yöntem: op_UnaryNegation)

  • Mantıksal Not işleç (karşılık gelen yöntem: op_OnesComplement)

  • IsTrue ve IsFalse işleçleri (karşılık gelen yöntemler: op_True, op_False)

Aşırı yüklenmiş tüm birli işleçler, içeren türün tek bir parametresini almalıdır ve ve dışında IsTrueIsFalseherhangi bir tür döndürebilir ve döndürmelidir Boolean. İçeren tür genel bir türse, tür parametreleri içeren türün tür parametreleriyle eşleşmelidir. Örneğin

Structure Complex
    ...

    Public Shared Operator +(v As Complex) As Complex
        Return v
    End Operator
End Structure

Bir tür veya IsFalsetüründen IsTrue birini aşırı yüklerse, diğerini de aşırı yüklemelidir. Yalnızca biri aşırı yüklenmişse derleme zamanı hatası oluşur.

Not. IsTrue ve IsFalse ayrılmış sözcükler değildir.

İkili İşleçler

Aşağıdaki ikili işleçler aşırı yüklenebilir:

  • Toplama +, çıkarma -, çarpma *, bölme /, integral bölme \, modül ve Mod üs ^ işleçleri (karşılık gelen yöntem: op_Addition, , op_Subtraction, op_Multiply, op_Division, op_IntegerDivision, , op_Modulus) op_Exponent

  • İlişkisel işleçler =, <>, <, >, <=, >= (karşılık gelen yöntemler: op_Equality, op_Inequality, op_LessThan, op_GreaterThan, , op_LessThanOrEqual). op_GreaterThanOrEqual Not. Eşitlik işleci aşırı yüklenebilir ancak atama işleci (yalnızca atama deyimlerinde kullanılır) aşırı yüklenemez.

  • işleci Like (karşılık gelen yöntem: op_Like)

  • Birleştirme işleci & (karşılık gelen yöntem: op_Concatenate)

  • Mantıksal Andve XorOr işleçleri (karşılık gelen yöntemler: op_BitwiseAnd, op_BitwiseOr, op_ExclusiveOr)

  • Shift işleçleri << ve >> (karşılık gelen yöntemler: op_LeftShift, op_RightShift)

Aşırı yüklenmiş tüm ikili işleçler, içeren türü parametrelerden biri olarak almalıdır. İçeren tür genel bir türse, tür parametreleri içeren türün tür parametreleriyle eşleşmelidir. Shift işleçleri bu kuralı, ilk parametrenin içeren türde olmasını gerektirecek şekilde daha da kısıtlar; ikinci parametre her zaman türünde Integerolmalıdır.

Aşağıdaki ikili işleçler çift olarak bildirilmelidir:

  • İşleç = ve işleç <>

  • İşleç > ve işleç <

  • İşleç >= ve işleç <=

Çiftlerden biri bildirilirse, diğeri de eşleşen parametre ve dönüş türleriyle bildirilmelidir, aksi takdirde derleme zamanı hatası oluşur. (Not. İlişkisel işleçlerin eşleştirilmiş bildirimlerine ihtiyaç duymanın amacı, aşırı yüklenmiş işleçlerde en az mantıksal tutarlılık düzeyini sağlamaya çalışmaktır.)

İlişkisel işleçlerin aksine, hem bölme hem de integral bölme işleçlerinin aşırı yüklenmesi kesinlikle önerilmez, ancak bir hata değildir. (Not. Genel olarak, iki bölme türü tamamen ayrı olmalıdır: bölmeyi destekleyen bir tür tam sayıdır (bu durumda desteklemelidir \) veya desteklememelidir (bu durumda desteklemelidir /). Her iki işleci tanımlamayı bir hata olarak değerlendirdik, ancak dilleri genellikle iki bölme türünü Visual Basic'in yaptığı gibi ayırt etmediğinden, uygulamaya izin vermenin en güvenli olduğunu ama kesinlikle önerilmez olduğunu düşündük.)

Bileşik atama işleçleri doğrudan aşırı yüklenemez. Bunun yerine, karşılık gelen ikili işleç aşırı yüklendiğinde bileşik atama işleci aşırı yüklenmiş işleci kullanır. Örneğin:

Structure Complex
    ...

    Public Shared Operator +(x As Complex, y As Complex) _
        As Complex
        ...
    End Operator
End Structure

Module Test
    Sub Main()
        Dim c1, c2 As Complex
        ' Calls the overloaded + operator
        c1 += c2
    End Sub
End Module

Dönüştürme İşleçleri

Dönüştürme işleçleri türler arasında yeni dönüştürmeler tanımlar. Bu yeni dönüştürmelere kullanıcı tanımlı dönüştürmeler adı verilir. Dönüştürme işleci, dönüştürme işlecinin parametre türüyle belirtilen bir kaynak türünden, dönüştürme işlecinin dönüş türüyle belirtilen hedef türe dönüştürür. Dönüştürmeler genişletme veya daraltma olarak sınıflandırılmalıdır. Anahtar sözcüğünü Widening içeren bir dönüştürme işleci bildirimi, kullanıcı tanımlı bir genişletme dönüştürmesi (karşılık gelen yöntem: op_Implicit) tanıtır. anahtar sözcüğünü Narrowing içeren bir dönüştürme işleci bildirimi, kullanıcı tanımlı bir daraltma dönüştürmesi (karşılık gelen yöntem: op_Explicit) tanıtır.

Genel olarak, kullanıcı tanımlı genişletme dönüştürmeleri hiçbir zaman özel durum oluşturmamak ve hiçbir zaman bilgi kaybetmemek için tasarlanmalıdır. Kullanıcı tanımlı bir dönüştürme özel durumlara (örneğin, kaynak bağımsız değişkeni aralık dışında olduğundan) veya bilgi kaybına (yüksek sıralı bitleri atma gibi) neden olabilirse, bu dönüştürme bir daraltma dönüştürmesi olarak tanımlanmalıdır. Örnekte:

Structure Digit
    Dim value As Byte

    Public Sub New(value As Byte)
        if value < 0 OrElse value > 9 Then Throw New ArgumentException()
        Me.value = value
    End Sub

    Public Shared Widening Operator CType(d As Digit) As Byte
        Return d.value
    End Operator

    Public Shared Narrowing Operator CType(b As Byte) As Digit
        Return New Digit(b)
    End Operator
End Structure

Digit Byte dönüştürmesi, hiçbir zaman özel durumlar oluşturmadığı veya bilgi kaybetmediği için genişletme dönüştürmesidir, ancak DigitByte dönüştürme işlemi daraltma dönüştürmedir çünkü Digit bir öğesinin olası değerlerinin Byteyalnızca bir alt kümesini temsil edebilir.

Aşırı yüklenebilen diğer tüm tür üyelerinden farklı olarak, dönüştürme işlecinin imzası dönüştürmenin hedef türünü içerir. Bu, dönüş türünün imzaya katıldığı tek tür üyesidir. Ancak, dönüştürme işlecinin genişletme veya daraltma sınıflandırması, işlecin imzasının bir parçası değildir. Bu nedenle, bir sınıf veya yapı hem bir genişletme dönüştürme işleci hem de aynı kaynak ve hedef türlerine sahip bir daraltma dönüştürme işleci bildiremez.

Kullanıcı tanımlı dönüştürme işlecini içeren türe veya türünden dönüştürmesi gerekir; örneğin, bir sınıfın C öğesinden IntegerC ve öğesinden CInteger öğesine dönüştürme tanımlaması mümkündür, ancak öğesinden Integer türüne Booleandönüştürülmemelidir. İçeren tür genel bir türse, tür parametreleri içeren türün tür parametreleriyle eşleşmelidir. Ayrıca, bir iç (kullanıcı tanımlı olmayan) dönüştürmeyi yeniden tanımlamak mümkün değildir. Sonuç olarak, bir tür aşağıdaki durumlarda bir dönüştürme bildiremez:

  • Kaynak türü ve hedef türü aynıdır.

  • Hem kaynak türü hem de hedef türü dönüştürme işlecini tanımlayan tür değildir.

  • Kaynak türü veya hedef türü bir arabirim türüdür.

  • Kaynak türü ve hedef türleri devralma ile ilişkilidir (dahil Object).

Bu kuralların tek özel durumu null atanabilir değer türleri için geçerlidir. Null atanabilir değer türlerinin gerçek tür tanımı olmadığından, değer türü türün null atanabilir sürümü için kullanıcı tanımlı dönüştürmeler bildirebilir. Bir türün belirli bir kullanıcı tanımlı dönüştürmeyi bildirip bildiremeyeceğini belirlerken, ? değiştiriciler önce geçerlilik denetimi amacıyla bildirimde yer alan tüm türlerden bırakılır. Bu nedenle, aşağıdaki bildirim için bir dönüştürme tanımlayabildiği için STgeçerlidirS:

Structure T
    ...
End Structure

Structure S
    Public Shared Widening Operator CType(ByVal v As S?) As T
    ...
    End Operator
End Structure

Ancak aşağıdaki bildirim geçerli değil, çünkü yapısı S 'den öğesine SSdönüştürme tanımlayamıyor:

Structure S
    Public Shared Widening Operator CType(ByVal v As S) As S?
        ...
    End Operator
End Structure

İşleç Eşlemesi

Visual Basic'in desteklediği işleç kümesi .NET Framework'te diğer dillerin sahip olduğu işleç kümesiyle tam olarak eşleşmeyebileceği için, bazı işleçler tanımlanırken veya kullanılırken diğer işleçlere özel olarak eşlenir. Özellikle:

  • İntegral bölme işlecini tanımlamak, integral bölme işlecini çağıracak bir normal bölme işlecini (yalnızca diğer dillerde kullanılabilir) otomatik olarak tanımlar.

  • Not, Andve işleçlerinin aşırı yüklenmesi, mantıksal ve Or bit düzeyinde işleçleri birbirinden ayıran diğer dillerin perspektifinden yalnızca bit düzeyinde işleci aşırı yükler.

  • Yalnızca mantıksal ve bit düzeyinde işleçleri (sırasıyla , ve için , op_LogicalAndve Andop_LogicalOrNotkullanan diller) birbirinden ayıran bir dildeki mantıksal işleçleri op_LogicalNotaşırı yükleyen bir sınıfın Ormantıksal işleçleri Visual Basic mantıksal işleçleriyle eşlenir. Hem mantıksal hem de bit düzeyinde işleçler aşırı yüklenmişse, yalnızca bit düzeyinde işleçler kullanılır.

  • << ve >> işleçlerinin aşırı yüklenmesi, yalnızca imzalı ve imzasız vardiya işleçlerini birbirinden ayıran diğer dillerin perspektifinden imzalı işleçleri aşırı yükler.

  • Yalnızca imzasız bir vardiya işlecini aşırı yükleyen bir sınıfta, işaretsiz vardiya işleci ilgili Visual Basic vardiya işlecine eşlenir. hem imzasız hem de imzalı vardiya işleci aşırı yüklenmişse, yalnızca imzalı vardiya işleci kullanılır.