Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Dua kategori dasar jenis di Visual Basic adalah jenis nilai dan jenis referensi. Jenis primitif (kecuali string), enumerasi, dan struktur adalah jenis nilai. Kelas, string, modul standar, antarmuka, array, dan delegasi adalah jenis referensi.
Setiap jenis memiliki nilai default, yang merupakan nilai yang ditetapkan ke variabel jenis tersebut setelah inisialisasi.
TypeName
: ArrayTypeName
| NonArrayTypeName
;
NonArrayTypeName
: SimpleTypeName
| NullableTypeName
;
SimpleTypeName
: QualifiedTypeName
| BuiltInTypeName
;
QualifiedTypeName
: Identifier TypeArguments? (Period IdentifierOrKeyword TypeArguments?)*
| 'Global' Period IdentifierOrKeyword TypeArguments?
(Period IdentifierOrKeyword TypeArguments?)*
;
TypeArguments
: OpenParenthesis 'Of' TypeArgumentList CloseParenthesis
;
TypeArgumentList
: TypeName ( Comma TypeName )*
;
BuiltInTypeName
: 'Object'
| PrimitiveTypeName
;
TypeModifier
: AccessModifier
| 'Shadows'
;
IdentifierModifiers
: NullableNameModifier? ArrayNameModifier?
;
Jenis Nilai dan Jenis Referensi
Meskipun jenis nilai dan jenis referensi dapat serupa dalam hal sintaksis dan penggunaan deklarasi, semantiknya berbeda.
Jenis referensi disimpan pada tumpukan run-time; mereka hanya dapat diakses melalui referensi ke penyimpanan tersebut. Karena jenis referensi selalu diakses melalui referensi, masa pakainya dikelola oleh .NET Framework. Referensi yang luar biasa ke instans tertentu dilacak dan instans dihancurkan hanya ketika tidak ada lagi referensi yang tersisa. Variabel jenis referensi berisi referensi ke nilai jenis tersebut, nilai jenis yang lebih turunan, atau nilai null. Nilai null mengacu pada apa-apa; tidak dimungkinkan untuk melakukan apa pun dengan nilai null kecuali menetapkannya. Penugasan ke variabel jenis referensi membuat salinan referensi daripada salinan nilai yang dirujuk. Untuk variabel jenis referensi, nilai defaultnya adalah nilai null.
Jenis nilai disimpan langsung di tumpukan, baik dalam array atau dalam jenis lain; penyimpanan mereka hanya dapat diakses secara langsung. Karena jenis nilai disimpan langsung dalam variabel, masa pakainya ditentukan oleh masa pakai variabel yang berisinya. Saat lokasi yang berisi instans jenis nilai dihancurkan, instans jenis nilai juga dihancurkan. Jenis nilai selalu diakses secara langsung; tidak dimungkinkan untuk membuat referensi ke jenis nilai. Melarang referensi seperti itu membuatnya tidak mungkin untuk merujuk ke instans kelas nilai yang telah dihancurkan. Karena jenis nilai selalu NotInheritable, variabel jenis nilai selalu berisi nilai dari jenis tersebut. Karena itu, nilai jenis nilai tidak boleh berupa nilai null, juga tidak dapat mereferensikan objek dengan jenis yang lebih turunan. Penugasan ke variabel jenis nilai membuat salinan nilai yang ditetapkan. Untuk variabel jenis nilai, nilai default adalah hasil menginisialisasi setiap anggota variabel dari jenis ke nilai defaultnya.
Contoh berikut menunjukkan perbedaan antara jenis referensi dan jenis nilai:
Class Class1
Public Value As Integer = 0
End Class
Module Test
Sub Main()
Dim val1 As Integer = 0
Dim val2 As Integer = val1
val2 = 123
Dim ref1 As Class1 = New Class1()
Dim ref2 As Class1 = ref1
ref2.Value = 123
Console.WriteLine("Values: " & val1 & ", " & val2)
Console.WriteLine("Refs: " & ref1.Value & ", " & ref2.Value)
End Sub
End Module
Output dari program adalah:
Values: 0, 123
Refs: 123, 123
Penugasan ke variabel val2 lokal tidak berdampak pada variabel val1 lokal karena kedua variabel lokal memiliki jenis nilai (jenis Integer) dan setiap variabel lokal dari jenis nilai memiliki penyimpanannya sendiri. Sebaliknya, penetapan ref2.Value = 123; memengaruhi objek yang dan ref1ref2 referensi.
Satu hal yang perlu diperhatikan tentang sistem jenis .NET Framework adalah bahwa meskipun struktur, enumerasi, dan jenis primitif (kecuali untuk String) adalah jenis nilai, semuanya diwarisi dari jenis referensi. Struktur dan jenis primitif mewarisi dari jenis System.ValueTypereferensi , yang mewarisi dari Object. Jenis enumerasi mewarisi dari jenis System.Enumreferensi , yang mewarisi dari System.ValueType.
Jenis Nilai yang Dapat Diubah Ke null
Untuk jenis nilai, ? pengubah dapat ditambahkan ke nama jenis untuk mewakili versi nullable dari jenis tersebut.
NullableTypeName
: NonArrayTypeName '?'
;
NullableNameModifier
: '?'
;
Jenis nilai nullable dapat berisi nilai yang sama dengan versi jenis yang tidak dapat diubah ke null serta nilai null. Dengan demikian, untuk jenis nilai nullable, menetapkan Nothing ke variabel jenis mengatur nilai variabel ke nilai null, bukan nilai nol dari jenis nilai. Contohnya:
Dim x As Integer = Nothing
Dim y As Integer? = Nothing
' Prints zero
Console.WriteLine(x)
' Prints nothing (because the value of y is the null value)
Console.WriteLine(y)
Variabel juga dapat dinyatakan sebagai jenis nilai nullable dengan menempatkan pengubah jenis nullable pada nama variabel. Untuk kejelasan, tidak valid untuk memiliki pengubah tipe null pada nama variabel dan nama jenis dalam deklarasi yang sama. Karena jenis nullable diimplementasikan menggunakan jenis System.Nullable(Of T), jenisnya T? identik dengan jenis System.Nullable(Of T), dan dua nama dapat digunakan secara bergantian. Pengubah ? tidak dapat ditempatkan pada jenis yang sudah nullable; dengan demikian, tidak mungkin untuk mendeklarasikan jenis Integer?? atau System.Nullable(Of Integer)?.
Jenis T? nilai nullable memiliki anggota System.Nullable(Of T) serta operator atau konversi apa pun yang diangkat dari jenis T yang mendasar ke dalam jenis T?. Mengangkat operator salinan dan konversi dari jenis yang mendasar, dalam kebanyakan kasus menggantikan jenis nilai nullable untuk jenis nilai yang tidak dapat diubah ke null. Ini memungkinkan banyak konversi dan operasi yang sama yang berlaku untuk T diterapkan T? juga.
Implementasi Antarmuka
Deklarasi struktur dan kelas dapat menyatakan bahwa mereka menerapkan serangkaian jenis antarmuka melalui satu atau beberapa Implements klausa.
TypeImplementsClause
: 'Implements' TypeImplements StatementTerminator
;
TypeImplements
: NonArrayTypeName ( Comma NonArrayTypeName )*
;
Semua jenis yang ditentukan dalam Implements klausa harus antarmuka, dan jenisnya harus mengimplementasikan semua anggota antarmuka. Contohnya:
Interface ICloneable
Function Clone() As Object
End Interface
Interface IComparable
Function CompareTo(other As Object) As Integer
End Interface
Structure ListEntry
Implements ICloneable, IComparable
...
Public Function Clone() As Object Implements ICloneable.Clone
...
End Function
Public Function CompareTo(other As Object) As Integer _
Implements IComparable.CompareTo
...
End Function
End Structure
Jenis yang mengimplementasikan antarmuka juga secara implisit mengimplementasikan semua antarmuka dasar antarmuka. Ini berlaku bahkan jika jenis tidak secara eksplisit mencantumkan semua antarmuka dasar dalam Implements klausa. Dalam contoh ini, TextBox struktur mengimplementasikan dan IControlITextBox.
Interface IControl
Sub Paint()
End Interface
Interface ITextBox
Inherits IControl
Sub SetText(text As String)
End Interface
Structure TextBox
Implements ITextBox
...
Public Sub Paint() Implements ITextBox.Paint
...
End Sub
Public Sub SetText(text As String) Implements ITextBox.SetText
...
End Sub
End Structure
Menyatakan bahwa jenis mengimplementasikan antarmuka dalam dan dari dirinya sendiri tidak mendeklarasikan apa pun dalam ruang deklarasi jenis. Dengan demikian, valid untuk mengimplementasikan dua antarmuka dengan metode dengan nama yang sama.
Jenis tidak dapat menerapkan parameter jenis sendiri, meskipun mungkin melibatkan parameter jenis yang berada dalam cakupan.
Class C1(Of V)
Implements V ' Error, can't implement type parameter directly
Implements IEnumerable(Of V) ' OK, not directly implementing
...
End Class
Antarmuka generik dapat diimplementasikan beberapa kali menggunakan argumen jenis yang berbeda. Namun, jenis generik tidak dapat menerapkan antarmuka generik menggunakan parameter jenis jika parameter jenis yang disediakan (terlepas dari batasan jenis) dapat tumpang tindih dengan implementasi lain dari antarmuka tersebut. Contohnya:
Interface I1(Of T)
End Interface
Class C1
Implements I1(Of Integer)
Implements I1(Of Double) ' OK, no overlap
End Class
Class C2(Of T)
Implements I1(Of Integer)
Implements I1(Of T) ' Error, T could be Integer
End Class
Jenis Primitif
Jenis primitif diidentifikasi melalui kata kunci, yang merupakan alias untuk jenis yang telah ditentukan sebelumnya di System namespace layanan. Jenis primitif benar-benar tidak dapat dibedakan dari jenis aliasnya: menulis kata Byte yang dipesan persis sama dengan menulis System.Byte. Jenis primitif juga dikenal sebagai jenis intrinsik.
PrimitiveTypeName
: NumericTypeName
| 'Boolean'
| 'Date'
| 'Char'
| 'String'
;
NumericTypeName
: IntegralTypeName
| FloatingPointTypeName
| 'Decimal'
;
IntegralTypeName
: 'Byte' | 'SByte' | 'UShort' | 'Short' | 'UInteger'
| 'Integer' | 'ULong' | 'Long'
;
FloatingPointTypeName
: 'Single' | 'Double'
;
Karena jenis primitif alias jenis biasa, setiap jenis primitif memiliki anggota. Misalnya, Integer meminta anggota dinyatakan dalam System.Int32. Literal dapat diperlakukan sebagai instans dari jenis yang sesuai.
Jenis primitif berbeda dari jenis struktur lain karena mereka mengizinkan operasi tambahan tertentu:
Jenis primitif mengizinkan nilai yang akan dibuat dengan menulis harfiah. Misalnya,
123Iadalah jenis harfiahInteger.Dimungkinkan untuk mendeklarasikan konstanta dari jenis primitif.
Ketika operand ekspresi adalah semua konstanta jenis primitif, dimungkinkan bagi pengompilasi untuk mengevaluasi ekspresi pada waktu kompilasi. Ekspresi seperti itu dikenal sebagai ekspresi konstanta.
Visual Basic mendefinisikan jenis primitif berikut:
Jenis
Bytenilai integral (bilangan bulat tanpa tanda 1 byte),SByte(bilangan bulat bertanda tangan 1 byte),UShort(bilangan bulat tanpa tanda 2 byte),Short(inte bertanda tangan 2 byteger),UInteger(bilangan bulat tanpa tanda 4 byte),Integer(bilangan bulat bertanda tangan 4 byte),ULong(bilangan bulat tanpa tanda 8 byte), danLong(bilangan bulat bertanda tangan 8 byte). Jenis ini masing-masing memetakan keSystem.Byte,System.SByteSystem.UInt16,System.Int16,System.UInt32,System.Int32,System.UInt64danSystem.Int64. Nilai default dari jenis integral setara dengan literal0.Jenis
Singlenilai floating-point (titik mengambang 4 byte) danDouble(titik mengambang 8 byte). Jenis-jenis ini masing-masing memetakan keSystem.SingledanSystem.Double, . Nilai default dari jenis floating-point setara dengan literal0.Jenis
Decimal(nilai desimal 16 byte), yang memetakan keSystem.Decimal. Nilai default desimal setara dengan literal0D.Jenis
Booleannilai, yang mewakili nilai kebenaran, biasanya hasil operasi relasional atau logis. Literalnya berjenisSystem.Boolean. Nilai default dariBooleanjenis ini setara dengan literalFalse.Jenis
Datenilai, yang mewakili tanggal dan/atau waktu dan peta keSystem.DateTime. Nilai default dariDatejenis ini setara dengan literal# 01/01/0001 12:00:00AM #.Jenis
Charnilai, yang mewakili satu karakter Unicode dan memetakan keSystem.Char. Nilai default jenisCharini setara dengan ekspresiChrW(0)konstanta .StringJenis referensi, yang mewakili urutan karakter Unicode dan peta keSystem.String. Nilai default jenisStringadalah nilai null.
Enumerasi
Enumerasi adalah jenis nilai yang mewarisi dari System.Enum dan secara simbolis mewakili sekumpulan nilai salah satu jenis integral primitif.
EnumDeclaration
: Attributes? TypeModifier* 'Enum' Identifier
( 'As' NonArrayTypeName )? StatementTerminator
EnumMemberDeclaration+
'End' 'Enum' StatementTerminator
;
Untuk jenis Eenumerasi , nilai defaultnya adalah nilai yang dihasilkan oleh ekspresi CType(0, E).
Jenis enumerasi yang mendasar harus merupakan jenis integral yang dapat mewakili semua nilai enumerator yang ditentukan dalam enumerasi. Jika jenis yang mendasar ditentukan, itu harus Byte, , SByte, UShort, Short, UIntegerInteger, ULong, Long, atau salah satu jenis yang sesuai di System namespace layanan. Jika tidak ada jenis yang mendasar yang ditentukan secara eksplisit, defaultnya adalah Integer.
Contoh berikut menyatakan enumerasi dengan jenis yang mendasar dari Long:
Enum Color As Long
Red
Green
Blue
End Enum
Pengembang mungkin memilih untuk menggunakan jenis Longyang mendasari , seperti dalam contoh, untuk mengaktifkan penggunaan nilai yang berada dalam rentang Long, tetapi tidak dalam rentang Integer, atau untuk mempertahankan opsi ini untuk masa depan.
Anggota Enumerasi
Anggota enumerasi adalah nilai enumerasi yang dideklarasikan dalam enumerasi dan anggota yang diwarisi dari kelas System.Enum.
Cakupan anggota enumerasi adalah badan deklarasi enumerasi. Ini berarti bahwa di luar deklarasi enumerasi, anggota enumerasi harus selalu memenuhi syarat (kecuali jenisnya diimpor secara khusus ke namespace melalui impor namespace).
Urutan deklarasi untuk deklarasi anggota enumerasi signifikan ketika nilai ekspresi konstanta dihilangkan. Anggota enumerasi secara implisit hanya memiliki Public akses; tidak ada pengubah akses yang diizinkan pada deklarasi anggota enumerasi.
EnumMemberDeclaration
: Attributes? Identifier ( Equals ConstantExpression )? StatementTerminator
;
Nilai Enumerasi
Nilai enumerasi dalam daftar anggota enumerasi dinyatakan sebagai konstanta yang diketik sebagai jenis enumerasi yang mendasar, dan dapat muncul di mana pun konstanta diperlukan. Definisi anggota enumerasi dengan = memberi anggota terkait nilai yang ditunjukkan oleh ekspresi konstanta. Ekspresi konstanta harus mengevaluasi ke jenis integral yang secara implisit dapat dikonversi ke jenis yang mendasar dan harus berada dalam rentang nilai yang dapat diwakili oleh jenis yang mendasar. Contoh berikut dalam kesalahan karena nilai 1.5konstanta , 2.3, dan 3.3 tidak secara implisit dapat dikonversi ke jenis Long integral yang mendasar dengan semantik yang ketat.
Option Strict On
Enum Color As Long
Red = 1.5
Green = 2.3
Blue = 3.3
End Enum
Beberapa anggota enumerasi dapat berbagi nilai terkait yang sama, seperti yang ditunjukkan di bawah ini:
Enum Color
Red
Green
Blue
Max = Blue
End Enum
Contoh menunjukkan enumerasi yang memiliki dua anggota enumerasi -- Blue dan Max -- yang memiliki nilai terkait yang sama.
Jika definisi nilai enumerator pertama dalam enumerasi tidak memiliki penginisialisasi, nilai konstanta yang sesuai adalah 0. Definisi nilai enumerasi tanpa penginisialisasi memberi enumerator nilai yang diperoleh dengan meningkatkan nilai nilai enumerasi sebelumnya dengan 1. Nilai yang ditingkatkan ini harus berada dalam rentang nilai yang dapat diwakili oleh jenis yang mendasar.
Enum Color
Red
Green = 10
Blue
End Enum
Module Test
Sub Main()
Console.WriteLine(StringFromColor(Color.Red))
Console.WriteLine(StringFromColor(Color.Green))
Console.WriteLine(StringFromColor(Color.Blue))
End Sub
Function StringFromColor(c As Color) As String
Select Case c
Case Color.Red
Return String.Format("Red = " & CInt(c))
Case Color.Green
Return String.Format("Green = " & CInt(c))
Case Color.Blue
Return String.Format("Blue = " & CInt(c))
Case Else
Return "Invalid color"
End Select
End Function
End Module
Contoh di atas mencetak nilai enumerasi dan nilai terkaitnya. Outputnya adalah:
Red = 0
Green = 10
Blue = 11
Alasan nilainya adalah sebagai berikut:
Nilai enumerasi
Redsecara otomatis diberi nilai0(karena tidak memiliki inisialisasi dan merupakan anggota nilai enumerasi pertama).Nilai enumerasi
Greensecara eksplisit diberikan nilai10.Nilai enumerasi
Bluesecara otomatis ditetapkan nilai satu lebih besar dari nilai enumerasi yang secara tekstual mendahuluinya.
Ekspresi konstanta mungkin tidak secara langsung atau tidak langsung menggunakan nilai nilai enumerasi terkaitnya sendiri (yaitu, melingkar dalam ekspresi konstanta tidak diizinkan). Contoh berikut tidak valid karena deklarasi A dan B melingkar.
Enum Circular
A = B
B
End Enum
A tergantung pada B secara eksplisit, dan B tergantung pada A secara implisit.
Kelas
Kelas adalah struktur data yang mungkin berisi anggota data (konstanta, variabel, dan peristiwa), anggota fungsi (metode, properti, pengindeks, operator, dan konstruktor), dan jenis berlapis. Kelas adalah jenis referensi.
ClassDeclaration
: Attributes? ClassModifier* 'Class' Identifier TypeParameterList? StatementTerminator
ClassBase?
TypeImplementsClause*
ClassMemberDeclaration*
'End' 'Class' StatementTerminator
;
ClassModifier
: TypeModifier
| 'MustInherit'
| 'NotInheritable'
| 'Partial'
;
Contoh berikut menunjukkan kelas yang berisi setiap jenis anggota:
Class AClass
Public Sub New()
Console.WriteLine("Constructor")
End Sub
Public Sub New(value As Integer)
MyVariable = value
Console.WriteLine("Constructor")
End Sub
Public Const MyConst As Integer = 12
Public MyVariable As Integer = 34
Public Sub MyMethod()
Console.WriteLine("MyClass.MyMethod")
End Sub
Public Property MyProperty() As Integer
Get
Return MyVariable
End Get
Set (value As Integer)
MyVariable = value
End Set
End Property
Default Public Property Item(index As Integer) As Integer
Get
Return 0
End Get
Set (value As Integer)
Console.WriteLine("Item(" & index & ") = " & value)
End Set
End Property
Public Event MyEvent()
Friend Class MyNestedClass
End Class
End Class
Contoh berikut menunjukkan penggunaan anggota ini:
Module Test
' Event usage.
Dim WithEvents aInstance As AClass
Sub Main()
' Constructor usage.
Dim a As AClass = New AClass()
Dim b As AClass = New AClass(123)
' Constant usage.
Console.WriteLine("MyConst = " & AClass.MyConst)
' Variable usage.
a.MyVariable += 1
Console.WriteLine("a.MyVariable = " & a.MyVariable)
' Method usage.
a.MyMethod()
' Property usage.
a.MyProperty += 1
Console.WriteLine("a.MyProperty = " & a.MyProperty)
a(1) = 1
' Event usage.
aInstance = a
End Sub
Sub MyHandler() Handles aInstance.MyEvent
Console.WriteLine("Test.MyHandler")
End Sub
End Module
Ada dua pengubah khusus kelas, MustInherit dan NotInheritable. Tidak valid untuk menentukan keduanya.
Spesifikasi Dasar Kelas
Deklarasi kelas dapat mencakup spesifikasi jenis dasar yang menentukan jenis dasar langsung kelas.
ClassBase
: 'Inherits' NonArrayTypeName StatementTerminator
;
Jika deklarasi kelas tidak memiliki jenis dasar eksplisit, jenis dasar langsung secara Objectimplisit . Contohnya:
Class Base
End Class
Class Derived
Inherits Base
End Class
Jenis dasar tidak dapat menjadi parameter jenis sendiri, meskipun mungkin melibatkan parameter jenis yang berada dalam cakupan.
Class C1(Of V)
End Class
Class C2(Of V)
Inherits V ' Error, type parameter used as base class
End Class
Class C3(Of V)
Inherits C1(Of V) ' OK: not directly inheriting from V.
End Class
Kelas hanya dapat berasal dari Object kelas dan . Ini tidak valid untuk kelas yang berasal dari System.ValueType, , System.EnumSystem.Array, System.MulticastDelegate atau System.Delegate. Kelas generik tidak dapat berasal dari System.Attribute atau dari kelas yang berasal dari kelas tersebut.
Setiap kelas memiliki tepat satu kelas dasar langsung, dan edaran dalam derivasi dilarang. Tidak dimungkinkan untuk berasal dari NotInheritable kelas, dan domain aksesibilitas kelas dasar harus sama dengan atau superset domain aksesibilitas kelas itu sendiri.
Anggota Kelas
Anggota kelas terdiri dari anggota yang diperkenalkan oleh deklarasi anggota kelasnya dan anggota yang diwarisi dari kelas dasar langsungnya.
ClassMemberDeclaration
: NonModuleDeclaration
| EventMemberDeclaration
| VariableMemberDeclaration
| ConstantMemberDeclaration
| MethodMemberDeclaration
| PropertyMemberDeclaration
| ConstructorMemberDeclaration
| OperatorDeclaration
;
Deklarasi anggota kelas mungkin memiliki Publicakses , , ProtectedFriend, Protected Friend, atau Private . Ketika deklarasi anggota kelas tidak menyertakan pengubah akses, deklarasi default untuk Public diakses, kecuali jika itu adalah deklarasi variabel; dalam hal ini default untuk Private diakses.
Cakupan anggota kelas adalah isi kelas tempat deklarasi anggota terjadi, ditambah daftar batasan kelas tersebut (jika generik dan memiliki batasan). Jika anggota memiliki Friend akses, cakupannya meluas ke isi kelas kelas mana pun dalam program yang sama atau rakitan apa pun yang telah diberikan Friend akses, dan jika anggota memiliki Public, , Protectedatau Protected Friend akses, cakupannya meluas ke isi kelas kelas mana pun dalam program apa pun.
Struktur
Struktur adalah jenis nilai yang mewarisi dari System.ValueType. Struktur mirip dengan kelas yang mewakili struktur data yang dapat berisi anggota data dan anggota fungsi. Namun, tidak seperti kelas, struktur tidak memerlukan alokasi timbunan.
StructureDeclaration
: Attributes? StructureModifier* 'Structure' Identifier
TypeParameterList? StatementTerminator
TypeImplementsClause*
StructMemberDeclaration*
'End' 'Structure' StatementTerminator
;
StructureModifier
: TypeModifier
| 'Partial'
;
Dalam kasus kelas, dimungkinkan bagi dua variabel untuk mereferensikan objek yang sama, dan dengan demikian mungkin untuk operasi pada satu variabel untuk memengaruhi objek yang dirujuk oleh variabel lain. Dengan struktur, variabel masing-masing memiliki salinan non-dataShared mereka sendiri, sehingga tidak mungkin bagi operasi pada satu untuk memengaruhi yang lain, seperti yang diilustrasikan contoh berikut:
Structure Point
Public x, y As Integer
Public Sub New(x As Integer, y As Integer)
Me.x = x
Me.y = y
End Sub
End Structure
Mengingat deklarasi di atas kode berikut menghasilkan nilai 10:
Module Test
Sub Main()
Dim a As New Point(10, 10)
Dim b As Point = a
a.x = 100
Console.WriteLine(b.x)
End Sub
End Module
Penugasan a untuk b membuat salinan nilai, dan b dengan demikian tidak terpengaruh oleh penugasan ke a.x. Sebaliknya Point telah dinyatakan sebagai kelas, outputnya adalah 100 karena a dan b akan mereferensikan objek yang sama.
Anggota Struktur
Anggota struktur adalah anggota yang diperkenalkan oleh deklarasi anggota strukturnya dan anggota yang diwarisi dari System.ValueType.
StructMemberDeclaration
: NonModuleDeclaration
| VariableMemberDeclaration
| ConstantMemberDeclaration
| EventMemberDeclaration
| MethodMemberDeclaration
| PropertyMemberDeclaration
| ConstructorMemberDeclaration
| OperatorDeclaration
;
Setiap struktur secara implisit memiliki Public konstruktor instans tanpa parameter yang menghasilkan nilai default struktur. Akibatnya, tidak dimungkinkan bagi deklarasi jenis struktur untuk mendeklarasikan konstruktor instans tanpa parameter. Namun, jenis struktur diizinkan untuk mendeklarasikan konstruktor instans berparameter , seperti dalam contoh berikut:
Structure Point
Private x, y As Integer
Public Sub New(x As Integer, y As Integer)
Me.x = x
Me.y = y
End Sub
End Structure
Mengingat deklarasi di atas, pernyataan berikut membuat Point dengan x dan y diinisialisasi menjadi nol.
Dim p1 As Point = New Point()
Dim p2 As Point = New Point(0, 0)
Karena struktur secara langsung berisi nilai bidangnya (daripada referensi ke nilai tersebut), struktur tidak dapat berisi bidang yang secara langsung atau tidak langsung mereferensikan sendiri. Misalnya, kode berikut tidak valid:
Structure S1
Dim f1 As S2
End Structure
Structure S2
' This would require S1 to contain itself.
Dim f1 As S1
End Structure
Biasanya, deklarasi anggota struktur hanya dapat memiliki Publicakses , Friend, atau Private , tetapi ketika mengambil alih anggota yang diwariskan dari Object, Protected dan Protected Friend akses juga dapat digunakan. Ketika deklarasi anggota struktur tidak menyertakan pengubah akses, deklarasi default untuk Public diakses. Ruang lingkup anggota yang dinyatakan oleh struktur adalah badan struktur tempat deklarasi terjadi, ditambah batasan struktur itu (jika generik dan memiliki kendala).
Modul Standar
Modul standar adalah jenis yang anggotanya secara Shared implisit dan terlingkup ke ruang deklarasi modul standar yang berisi namespace, bukan hanya untuk deklarasi modul standar itu sendiri. Modul standar mungkin tidak pernah dibuat instans. Ini adalah kesalahan untuk mendeklarasikan variabel jenis modul standar.
ModuleDeclaration
: Attributes? TypeModifier* 'Module' Identifier StatementTerminator
ModuleMemberDeclaration*
'End' 'Module' StatementTerminator
;
Anggota modul standar memiliki dua nama yang sepenuhnya memenuhi syarat, satu tanpa nama modul standar dan satu dengan nama modul standar. Lebih dari satu modul standar dalam namespace layanan dapat menentukan anggota dengan nama tertentu; referensi yang tidak memenuhi syarat ke nama di luar salah satu modul bersifat ambigu. Contohnya:
Namespace N1
Module M1
Sub S1()
End Sub
Sub S2()
End Sub
End Module
Module M2
Sub S2()
End Sub
End Module
Module M3
Sub Main()
S1() ' Valid: Calls N1.M1.S1.
N1.S1() ' Valid: Calls N1.M1.S1.
S2() ' Not valid: ambiguous.
N1.S2() ' Not valid: ambiguous.
N1.M2.S2() ' Valid: Calls N1.M2.S2.
End Sub
End Module
End Namespace
Modul hanya dapat dideklarasikan dalam namespace layanan dan mungkin tidak ditumpuk dalam jenis lain. Modul standar mungkin tidak menerapkan antarmuka, mereka secara implisit berasal dari Object, dan mereka hanya Shared memiliki konstruktor.
Anggota Modul Standar
Anggota modul standar adalah anggota yang diperkenalkan oleh deklarasi anggotanya dan anggota yang diwarisi dari Object. Modul standar mungkin memiliki semua jenis anggota kecuali konstruktor instans. Semua anggota jenis modul standar secara Sharedimplisit .
ModuleMemberDeclaration
: NonModuleDeclaration
| VariableMemberDeclaration
| ConstantMemberDeclaration
| EventMemberDeclaration
| MethodMemberDeclaration
| PropertyMemberDeclaration
| ConstructorMemberDeclaration
;
Biasanya, deklarasi anggota modul standar hanya dapat memiliki Publicakses , , Friendatau Private , tetapi ketika mengambil alih anggota yang diwariskan dari Object, Protected pengubah akses dan Protected Friend dapat ditentukan. Ketika deklarasi anggota modul standar tidak menyertakan pengubah akses, deklarasi default untuk Public diakses, kecuali itu adalah variabel, yang default untuk Private diakses.
Seperti yang disebutkan sebelumnya, cakupan anggota modul standar adalah deklarasi yang berisi deklarasi modul standar. Anggota yang diwariskan dari Object tidak termasuk dalam cakupan khusus ini; anggota tersebut tidak memiliki cakupan dan harus selalu memenuhi syarat dengan nama modul. Jika anggota memiliki Friend akses, cakupannya hanya meluas ke anggota namespace yang dideklarasikan dalam program atau rakitan yang sama yang telah diberikan Friend akses.
Antarmuka
Antarmuka adalah jenis referensi yang diterapkan jenis lain untuk menjamin bahwa mereka mendukung metode tertentu. Antarmuka tidak pernah dibuat secara langsung dan tidak memiliki representasi aktual -- jenis lain harus dikonversi ke jenis antarmuka. Antarmuka mendefinisikan kontrak. Kelas atau struktur yang mengimplementasikan antarmuka harus mematuhi kontraknya.
InterfaceDeclaration
: Attributes? TypeModifier* 'Interface' Identifier
TypeParameterList? StatementTerminator
InterfaceBase*
InterfaceMemberDeclaration*
'End' 'Interface' StatementTerminator
;
Contoh berikut menunjukkan antarmuka yang berisi properti Itemdefault , peristiwa E, metode F, dan properti P:
Interface IExample
Default Property Item(index As Integer) As String
Event E()
Sub F(value As Integer)
Property P() As String
End Interface
Antarmuka dapat menggunakan beberapa pewarisan. Dalam contoh berikut, antarmuka IComboBox mewarisi dari dan ITextBoxIListBox:
Interface IControl
Sub Paint()
End Interface
Interface ITextBox
Inherits IControl
Sub SetText(text As String)
End Interface
Interface IListBox
Inherits IControl
Sub SetItems(items() As String)
End Interface
Interface IComboBox
Inherits ITextBox, IListBox
End Interface
Kelas dan struktur dapat mengimplementasikan beberapa antarmuka. Dalam contoh berikut, kelas EditBox berasal dari kelas Control dan mengimplementasikan dan IControlIDataBound:
Interface IDataBound
Sub Bind(b As Binder)
End Interface
Public Class EditBox
Inherits Control
Implements IControl, IDataBound
Public Sub Paint() Implements IControl.Paint
...
End Sub
Public Sub Bind(b As Binder) Implements IDataBound.Bind
...
End Sub
End Class
Pewarisan Antarmuka
Antarmuka dasar antarmuka adalah antarmuka dasar eksplisit dan antarmuka dasarnya. Dengan kata lain, himpunan antarmuka dasar adalah penutupan transitif yang lengkap dari antarmuka dasar eksplisit, antarmuka dasar eksplisit mereka, dan seterusnya. Jika deklarasi antarmuka tidak memiliki basis antarmuka eksplisit, maka tidak ada antarmuka dasar untuk jenis -- antarmuka tidak mewarisi dari Object (meskipun mereka memiliki konversi yang melebar ke Object).
InterfaceBase
: 'Inherits' InterfaceBases StatementTerminator
;
InterfaceBases
: NonArrayTypeName ( Comma NonArrayTypeName )*
;
Dalam contoh berikut, antarmuka IComboBox dasar adalah IControl, , ITextBoxdan IListBox.
Interface IControl
Sub Paint()
End Interface
Interface ITextBox
Inherits IControl
Sub SetText(text As String)
End Interface
Interface IListBox
Inherits IControl
Sub SetItems(items() As String)
End Interface
Interface IComboBox
Inherits ITextBox, IListBox
End Interface
Antarmuka mewarisi semua anggota antarmuka dasarnya. Dengan kata lain, IComboBox antarmuka di atas mewarisi anggota SetText dan SetItems serta Paint.
Kelas atau struktur yang mengimplementasikan antarmuka juga secara implisit mengimplementasikan semua antarmuka dasar antarmuka.
Jika antarmuka muncul lebih dari sekali dalam penutupan transitif antarmuka dasar, antarmuka hanya menyumbangkan anggotanya ke antarmuka turunan sekali. Jenis yang mengimplementasikan antarmuka turunan hanya perlu mengimplementasikan metode antarmuka dasar yang ditentukan perkalian sekali. Dalam contoh berikut, Paint hanya perlu diimplementasikan sekali, meskipun kelas mengimplementasikan IComboBox dan IControl.
Class ComboBox
Implements IControl, IComboBox
Sub SetText(text As String) Implements IComboBox.SetText
End Sub
Sub SetItems(items() As String) Implements IComboBox.SetItems
End Sub
Sub Print() Implements IComboBox.Paint
End Sub
End Class
Klausa Inherits tidak berpengaruh pada klausul lain Inherits . Dalam contoh berikut, IDerived harus memenuhi syarat nama INested dengan IBase.
Interface IBase
Interface INested
Sub Nested()
End Interface
Sub Base()
End Interface
Interface IDerived
Inherits IBase, INested ' Error: Must specify IBase.INested.
End Interface
Domain aksesibilitas antarmuka dasar harus sama dengan atau superset domain aksesibilitas antarmuka itu sendiri.
Anggota Antarmuka
Anggota antarmuka terdiri dari anggota yang diperkenalkan oleh deklarasi anggotanya dan anggota yang diwarisi dari antarmuka dasarnya.
InterfaceMemberDeclaration
: NonModuleDeclaration
| InterfaceEventMemberDeclaration
| InterfaceMethodMemberDeclaration
| InterfacePropertyMemberDeclaration
;
Meskipun antarmuka tidak mewarisi anggota dari Object, karena setiap kelas atau struktur yang mengimplementasikan antarmuka mewarisi dari Object, anggota Object, termasuk metode ekstensi, dianggap sebagai anggota antarmuka dan dapat dipanggil pada antarmuka secara langsung tanpa memerlukan transmisi ke Object. Contohnya:
Interface I1
End Interface
Class C1
Implements I1
End Class
Module Test
Sub Main()
Dim i As I1 = New C1()
Dim h As Integer = i.GetHashCode()
End Sub
End Module
Anggota antarmuka dengan nama yang sama dengan anggota Object anggota bayangan Object implisit. Hanya jenis, metode, properti, dan peristiwa berlapis yang mungkin merupakan anggota antarmuka. Metode dan properti mungkin tidak memiliki isi. Anggota antarmuka secara Public implisit dan mungkin tidak menentukan pengubah akses. Cakupan anggota yang dideklarasikan dalam antarmuka adalah isi antarmuka tempat deklarasi terjadi, ditambah daftar batasan antarmuka tersebut (jika umum dan memiliki batasan).
Larik
Array adalah jenis referensi yang berisi variabel yang diakses melalui indeks yang sesuai dengan cara satu-ke-satu dengan urutan variabel dalam array. Variabel yang terkandung dalam array, juga disebut elemen array, semuanya harus dari jenis yang sama, dan jenis ini disebut jenis elemen array.
ArrayTypeName
: NonArrayTypeName ArrayTypeModifiers
;
ArrayTypeModifiers
: ArrayTypeModifier+
;
ArrayTypeModifier
: OpenParenthesis RankList? CloseParenthesis
;
RankList
: Comma*
;
ArrayNameModifier
: ArrayTypeModifiers
| ArraySizeInitializationModifier
;
Elemen array muncul ketika instans array dibuat, dan berhenti ada saat instans array dihancurkan. Setiap elemen array diinisialisasi ke nilai default dari jenisnya. Jenisnya System.Array adalah jenis dasar dari semua jenis array dan mungkin tidak dibuat. Setiap jenis array mewarisi anggota yang dideklarasikan oleh System.Array jenis dan dapat dikonversi ke dalamnya (dan Object). Jenis array satu dimensi dengan elemen T juga mengimplementasikan antarmuka System.Collections.Generic.IList(Of T) dan IReadOnlyList(Of T); jika T merupakan jenis referensi, maka jenis array juga mengimplementasikan IList(Of U) dan IReadOnlyList(Of U) untuk apa pun U yang memiliki konversi referensi yang melebar dari T.
Array memiliki peringkat yang menentukan jumlah indeks yang terkait dengan setiap elemen array. Peringkat array menentukan jumlah dimensi array. Misalnya, array dengan peringkat satu disebut array dimensi tunggal, dan array dengan peringkat yang lebih besar dari satu disebut array multidimensi.
Contoh berikut membuat array dimensi tunggal dari nilai bilangan bulat, menginisialisasi elemen array, lalu mencetak masing-masing nilai bilangan bulat:
Module Test
Sub Main()
Dim arr(5) As Integer
Dim i As Integer
For i = 0 To arr.Length - 1
arr(i) = i * i
Next i
For i = 0 To arr.Length - 1
Console.WriteLine("arr(" & i & ") = " & arr(i))
Next i
End Sub
End Module
Program menghasilkan yang berikut:
arr(0) = 0
arr(1) = 1
arr(2) = 4
arr(3) = 9
arr(4) = 16
arr(5) = 25
Setiap dimensi array memiliki panjang terkait. Panjang dimensi bukan bagian dari jenis array, melainkan ditetapkan ketika instans jenis array dibuat pada waktu proses. Panjang dimensi menentukan rentang indeks yang valid untuk dimensi tersebut: untuk dimensi panjang N, indeks dapat berkisar dari nol hingga N-1. Jika dimensi memiliki panjang nol, tidak ada indeks yang valid untuk dimensi tersebut. Jumlah total elemen dalam array adalah produk dari panjang setiap dimensi dalam array. Jika salah satu dimensi array memiliki panjang nol, array dikatakan kosong. Jenis elemen array dapat berupa jenis apa pun.
Jenis array ditentukan dengan menambahkan pengubah ke nama tipe yang sudah ada. Pengubah terdiri dari tanda kurung kiri, satu set koma nol atau lebih, dan tanda kurung kanan. Jenis yang dimodifikasi adalah jenis elemen array, dan jumlah dimensi adalah jumlah koma ditambah satu. Jika lebih dari satu pengubah ditentukan, maka jenis elemen array adalah array. Pengubah dibaca dari kiri ke kanan, dengan pengubah paling kiri menjadi array terluar. Dalam contoh
Module Test
Dim arr As Integer(,)(,,)()
End Module
jenis arr elemen adalah array dua dimensi dari array tiga dimensi dari array satu dimensi .Integer
Variabel juga dapat dinyatakan dari jenis array dengan menempatkan pengubah jenis array atau pengubah inisialisasi ukuran array pada nama variabel. Dalam hal ini, jenis elemen array adalah jenis yang diberikan dalam deklarasi, dan dimensi array ditentukan oleh pengubah nama variabel. Untuk kejelasan, tidak valid untuk memiliki pengubah jenis array pada nama variabel dan nama jenis dalam deklarasi yang sama.
Contoh berikut menunjukkan berbagai deklarasi variabel lokal yang menggunakan jenis array dengan Integer sebagai jenis elemen:
Module Test
Sub Main()
Dim a1() As Integer ' Declares 1-dimensional array of integers.
Dim a2(,) As Integer ' Declares 2-dimensional array of integers.
Dim a3(,,) As Integer ' Declares 3-dimensional array of integers.
Dim a4 As Integer() ' Declares 1-dimensional array of integers.
Dim a5 As Integer(,) ' Declares 2-dimensional array of integers.
Dim a6 As Integer(,,) ' Declares 3-dimensional array of integers.
' Declare 1-dimensional array of 2-dimensional arrays of integers
Dim a7()(,) As Integer
' Declare 2-dimensional array of 1-dimensional arrays of integers.
Dim a8(,)() As Integer
Dim a9() As Integer() ' Not allowed.
End Sub
End Module
Pengubah nama jenis array meluas ke semua set tanda kurung yang mengikutinya. Ini berarti bahwa dalam situasi di mana sekumpulan argumen yang diapit dalam tanda kurung diizinkan setelah nama jenis, tidak dimungkinkan untuk menentukan argumen untuk nama jenis array. Contohnya:
Module Test
Sub Main()
' This calls the Integer constructor.
Dim x As New Integer(3)
' This declares a variable of Integer().
Dim y As Integer()
' This gives an error.
' Array sizes can not be specified in a type name.
Dim z As Integer()(3)
End Sub
End Module
Dalam kasus terakhir, (3) ditafsirkan sebagai bagian dari nama jenis daripada sebagai sekumpulan argumen konstruktor.
Perwakilan
Delegasi adalah jenis referensi yang mengacu pada Shared metode jenis atau ke metode instans objek.
DelegateDeclaration
: Attributes? TypeModifier* 'Delegate' MethodSignature StatementTerminator
;
MethodSignature
: SubSignature
| FunctionSignature
;
Yang paling setara dengan delegasi dalam bahasa lain adalah penunjuk fungsi, tetapi sedangkan penunjuk fungsi hanya dapat mereferensikan Shared fungsi, delegasi dapat mereferensikan metode dan Shared instans. Dalam kasus terakhir, delegasi tidak hanya menyimpan referensi ke titik masuk metode, tetapi juga referensi ke instans objek untuk memanggil metode .
Deklarasi delegasi mungkin tidak memiliki Handles klausa, Implements klausa, isi metode, atau End konstruksi. Daftar parameter deklarasi delegasi mungkin tidak berisi Optional parameter atau ParamArray . Domain aksesibilitas jenis pengembalian dan jenis parameter harus sama dengan atau superset domain aksesibilitas delegasi itu sendiri.
Anggota delegasi adalah anggota yang diwarisi dari kelas System.Delegate. Delegasi juga menentukan metode berikut:
Konstruktor yang mengambil dua parameter, salah satu jenis
Objectdan salah satu jenisSystem.IntPtr.Metode
Invokeyang memiliki tanda tangan yang sama dengan delegasi.BeginInvokeMetode yang tanda tangannya adalah tanda tangan delegasi, dengan tiga perbedaan. Pertama, jenis pengembalian diubah menjadiSystem.IAsyncResult. Kedua, dua parameter tambahan ditambahkan ke akhir daftar parameter: yang pertama dari jenisSystem.AsyncCallbackdan yang kedua dari jenisObject. Dan akhirnya, semuaByRefparameter diubah menjadiByVal.Metode
EndInvokeyang jenis pengembaliannya sama dengan delegasi. Parameter metode hanyalah parameter delegasi persis yang merupakanByRefparameter, dalam urutan yang sama terjadi dalam tanda tangan delegasi. Selain parameter tersebut, ada parameter tambahan jenisSystem.IAsyncResultdi akhir daftar parameter.
Ada tiga langkah dalam menentukan dan menggunakan delegasi: deklarasi, instansiasi, dan pemanggilan.
Delegasi dinyatakan menggunakan sintaks deklarasi delegasi. Contoh berikut mendeklarasikan delegasi bernama SimpleDelegate yang tidak mengambil argumen:
Delegate Sub SimpleDelegate()
Contoh berikutnya membuat SimpleDelegate instans lalu segera memanggilnya:
Module Test
Sub F()
System.Console.WriteLine("Test.F")
End Sub
Sub Main()
Dim d As SimpleDelegate = AddressOf F
d()
End Sub
End Module
Tidak ada banyak titik dalam membuat instans delegasi untuk metode dan kemudian segera memanggil melalui delegasi, karena akan lebih mudah untuk memanggil metode secara langsung. Delegasi menunjukkan kegunaannya ketika anonimitasnya digunakan. Contoh berikutnya menunjukkan MultiCall metode yang berulang kali memanggil instans SimpleDelegate :
Sub MultiCall(d As SimpleDelegate, count As Integer)
Dim i As Integer
For i = 0 To count - 1
d()
Next i
End Sub
Tidak penting untuk MultiCall metode apa metode target untuk SimpleDelegate itu, aksesibilitas apa yang dimiliki metode ini, atau apakah metode tersebut Shared atau tidak. Yang penting adalah bahwa tanda tangan metode target kompatibel dengan SimpleDelegate.
Jenis parsial
Deklarasi kelas dan struktur dapat berupa deklarasi parsial . Deklarasi parsial mungkin atau mungkin tidak sepenuhnya menjelaskan jenis yang dinyatakan dalam deklarasi. Sebaliknya, deklarasi jenis dapat tersebar di beberapa deklarasi parsial dalam program; tipe parsial tidak dapat dideklarasikan di seluruh batas program. Deklarasi jenis parsial menentukan pengubah Partial pada deklarasi. Kemudian, deklarasi lain dalam program untuk jenis dengan nama yang sepenuhnya memenuhi syarat yang sama akan digabungkan bersama dengan deklarasi parsial pada waktu kompilasi untuk membentuk deklarasi jenis tunggal. Misalnya, kode berikut mendeklarasikan satu kelas Test dengan anggota Test.C1 dan Test.C2.
a.vb:
Public Partial Class Test
Public Sub S1()
End Sub
End Class
b.vb:
Public Class Test
Public Sub S2()
End Sub
End Class
Saat menggabungkan deklarasi jenis parsial, setidaknya salah satu deklarasi harus memiliki Partial pengubah, jika tidak, hasil kesalahan waktu kompilasi.
Nota. Meskipun dimungkinkan untuk menentukan Partial hanya pada satu deklarasi di antara banyak deklarasi parsial, itu adalah bentuk yang lebih baik untuk menentukannya pada semua deklarasi parsial. Dalam situasi di mana satu deklarasi parsial terlihat tetapi satu atau beberapa deklarasi parsial disembunyikan (seperti kasus perluasan kode yang dihasilkan alat), dapat diterima untuk membiarkan Partial pengubah keluar dari deklarasi yang terlihat tetapi menentukannya pada deklarasi tersembunyi.
Hanya kelas dan struktur yang dapat dideklarasikan menggunakan deklarasi parsial. Aritas jenis dipertimbangkan saat mencocokkan deklarasi parsial bersama-sama: dua kelas dengan nama yang sama tetapi jumlah parameter jenis yang berbeda tidak dianggap sebagai deklarasi parsial pada saat yang sama. Deklarasi parsial dapat menentukan atribut, pengubah kelas, pernyataan, Inherits atau Implements pernyataan. Pada waktu kompilasi, semua potongan deklarasi parsial digabungkan bersama-sama dan digunakan sebagai bagian dari deklarasi jenis. Jika ada konflik antara atribut, pengubah, basis, antarmuka, atau anggota jenis, hasil kesalahan waktu kompilasi. Contohnya:
Public Partial Class Test1
Implements IDisposable
End Class
Class Test1
Inherits Object
Implements IComparable
End Class
Public Partial Class Test2
End Class
Private Partial Class Test2
End Class
Contoh sebelumnya mendeklarasikan jenis Test1 yaitu Public, mewarisi dari Object dan mengimplementasikan System.IDisposable dan System.IComparable. Deklarasi parsial Test2 akan menyebabkan kesalahan kompilasi-waktu karena salah satu deklarasi mengatakan bahwa Test2 adalah Public dan yang lain mengatakan yaitu Test2Private.
Jenis parsial dengan parameter jenis dapat mendeklarasikan batasan dan varians untuk parameter jenis, tetapi batasan dan varians dari setiap deklarasi parsial harus cocok. Dengan demikian, batasan dan varians khusus karena tidak digabungkan secara otomatis seperti pengubah lain:
Partial Public Class List(Of T As IEnumerable)
End Class
' Error: Constraints on T don't match
Class List(Of T As IComparable)
End Class
Fakta bahwa jenis dinyatakan menggunakan beberapa deklarasi parsial tidak memengaruhi aturan pencarian nama dalam jenis tersebut. Akibatnya, deklarasi jenis parsial dapat menggunakan anggota yang dideklarasikan dalam deklarasi jenis parsial lainnya, atau dapat menerapkan metode pada antarmuka yang dideklarasikan dalam deklarasi jenis parsial lainnya. Contohnya:
Public Partial Class Test1
Implements IDisposable
Private IsDisposed As Boolean = False
End Class
Class Test1
Private Sub Dispose() Implements IDisposable.Dispose
If Not IsDisposed Then
...
End If
End Sub
End Class
Jenis berlapis juga dapat memiliki deklarasi parsial. Contohnya:
Public Partial Class Test
Public Partial Class NestedTest
Public Sub S1()
End Sub
End Class
End Class
Public Partial Class Test
Public Partial Class NestedTest
Public Sub S2()
End Sub
End Class
End Class
Inisialisasi dalam deklarasi parsial masih akan dijalankan dalam urutan deklarasi; namun, tidak ada jaminan urutan eksekusi untuk inisialisasi yang terjadi dalam deklarasi parsial terpisah.
Jenis yang Dibangun
Deklarasi jenis generik, dengan sendirinya, tidak menunjukkan jenis. Sebagai gantinya, deklarasi jenis generik dapat digunakan sebagai "cetak biru" untuk membentuk berbagai jenis dengan menerapkan argumen jenis. Jenis generik yang memiliki jenis argumen yang diterapkan padanya disebut jenis yang dibangun. Argumen jenis dalam jenis yang dibangun harus selalu memenuhi batasan yang ditempatkan pada parameter jenis yang cocok dengannya.
Nama jenis mungkin mengidentifikasi jenis yang dibangun meskipun tidak menentukan parameter jenis secara langsung. Ini dapat terjadi di mana jenis disarangkan dalam deklarasi kelas generik, dan jenis instans deklarasi yang berisi secara implisit digunakan untuk pencarian nama:
Class Outer(Of T)
Public Class Inner
End Class
' Type of i is the constructed type Outer(Of T).Inner
Public i As Inner
End Class
Jenis C(Of T1,...,Tn) yang dibangun dapat diakses ketika jenis generik dan semua argumen jenis dapat diakses. Misalnya, jika jenis C generik adalah Public dan semua argumen T1,...,Tn jenis adalah Public, maka jenis yang dibangun adalah Public. Namun, jika nama jenis atau salah satu argumen jenis adalah Private, maka aksesibilitas jenis yang dibangun adalah Private. Jika satu jenis argumen dari jenis yang dibangun adalah Protected dan argumen jenis lain adalah Friend, maka jenis yang dibangun hanya dapat diakses di kelas dan subkelasnya dalam rakitan ini atau rakitan apa pun yang telah diberikan Friend akses. Dengan kata lain, domain aksesibilitas untuk jenis yang dibangun adalah persimpangan domain aksesibilitas dari bagian konstituennya.
Nota. Fakta bahwa domain aksesibilitas jenis yang dibangun adalah persimpangan bagian yang merupakan bagian-bagiannya memiliki efek samping yang menarik untuk menentukan tingkat aksesibilitas baru. Jenis yang dibangun yang berisi elemen yang merupakan Protected elemen dan elemen yang Friend hanya dapat diakses dalam konteks yang dapat mengakses anggotadanProtected.Friend Namun, tidak ada cara untuk mengekspresikan tingkat aksesibilitas ini dalam bahasa, karena aksesibilitas Protected Friend berarti bahwa entitas dapat diakses dalam konteks yang dapat mengakses salah satuFriendatauProtected anggota.
Dasar, antarmuka yang diimplementasikan, dan anggota jenis yang dibangun ditentukan dengan mengganti argumen jenis yang disediakan untuk setiap kemunculan parameter jenis dalam jenis generik.
Jenis Terbuka dan Jenis Tertutup
Jenis yang dibangun untuk siapa satu atau beberapa argumen jenis adalah parameter jenis dari jenis atau metode yang berisi disebut jenis terbuka. Ini karena beberapa parameter jenis jenis masih belum diketahui, sehingga bentuk sebenarnya dari jenis belum sepenuhnya diketahui. Sebaliknya, jenis generik yang argumen jenisnya adalah semua parameter non-jenis disebut jenis tertutup. Bentuk jenis tertutup selalu diketahui sepenuhnya. Contohnya:
Class Base(Of T, V)
End Class
Class Derived(Of V)
Inherits Base(Of Integer, V)
End Class
Class MoreDerived
Inherits Derived(Of Double)
End Class
Jenis Base(Of Integer, V) yang dibangun adalah jenis terbuka karena meskipun parameter T jenis telah disediakan, parameter U jenis telah diberikan parameter jenis lain. Dengan demikian, bentuk lengkap jenisnya belum diketahui. Jenis Derived(Of Double)yang dibangun , namun, adalah jenis tertutup karena semua parameter jenis dalam hierarki warisan telah disediakan.
Jenis terbuka didefinisikan sebagai berikut:
Parameter jenis adalah jenis terbuka.
Jenis array adalah jenis terbuka jika jenis elemennya adalah jenis terbuka.
Jenis yang dibangun adalah jenis terbuka jika satu atau beberapa argumen jenisnya adalah jenis terbuka.
Jenis tertutup adalah tipe yang bukan tipe terbuka.
Karena titik entri program tidak dapat berada dalam tipe generik, semua jenis yang digunakan pada run-time akan ditutup.
Jenis Khusus
.NET Framework berisi sejumlah kelas yang diperlakukan khusus oleh .NET Framework dan oleh bahasa Visual Basic:
Jenis System.Void, yang mewakili jenis kekosongan dalam .NET Framework, dapat langsung direferensikan hanya dalam GetType ekspresi.
Jenis System.RuntimeArgumentHandle, System.ArgIterator dan System.TypedReference semua dapat berisi pointer ke dalam tumpukan sehingga tidak dapat muncul pada tumpukan .NET Framework. Oleh karena itu, mereka tidak dapat digunakan sebagai jenis elemen array, jenis pengembalian, jenis bidang, argumen jenis generik, jenis nullable, ByRef jenis parameter, jenis nilai yang dikonversi ke Object atau System.ValueType, target panggilan ke anggota Object instans atau System.ValueType, atau diangkat ke dalam penutupan.
Visual Basic language spec