A Visual Basic .NET program is a set of source files that the compiler reads together, so files may refer to each other in any order and a declaration needs no forward declaration. This page describes what one file holds, in what order, and the conventions around it.
The layout of a file
A source file is, in this order: optional Option statements, optional Imports statements, optional attributes that apply to the assembly or module, and then namespace members (namespaces, modules, classes, structures, interfaces, enumerations and delegates). The members at the top level of the file belong to the global namespace (the project’s root namespace is added in front of them by the compiler options).
Option Explicit On
Option Strict On
Option Infer On
Option Compare Text
Imports System.Collections.Generic
Imports IO = System.IO
Imports <xmlns:db="http://example.com/db">
<Assembly: System.Reflection.AssemblyDescription("Demo")>
Namespace Shop.Orders
Public Class Order
Public Property Lines As New List(Of String)
Public Function Exists(path As String) As Boolean
Return IO.File.Exists(path)
End Function
End Class
End Namespace
Public Module Startup
Public Function Main(args() As String) As Integer
Return 0
End Function
End Module
Statements end at the end of a line or at a colon (a = 1 : b = 2). A line can be continued with an underscore or, in many places, simply by breaking it after a comma, an opening bracket or an operator (see lexical structure). Blocks are closed by an End statement or its own closer (Next, Loop, Wend); there is no brace syntax except for collection and array initialisers.
Option statements
An Option statement applies to the file it is in, and each of the four kinds may appear once. If a file leaves one out, the compiler options of the project decide (the project properties, or /optionexplicit, /optionstrict, /optioninfer and /optioncompare of vbc).
| Statement | Meaning |
|---|---|
Option Explicit On|Off | whether a local variable must be declared; with it off, assigning to an unknown name declares a local of type Object. Without On or Off the default is On |
Option Strict On|Off | strict type semantics: no narrowing conversion without a cast, no late binding, no operation on Object except TypeOf…Is, Is and IsNot, and every declaration needs a type (an As clause or an inferred type) |
Option Compare Binary|Text | how strings compare: by the Unicode value of each character, or by the current culture’s text rules (so "a" = "A" is true under Text) |
Option Infer On|Off | whether a local declaration without As takes the type of its initialiser (Dim x = 10 is an Integer) or is Object |
Explicit, Strict, Infer, Compare, Binary, Text, On and Off are not reserved words; they are only keywords after Option (On is reserved for other uses). A fifth option, integer overflow checking, can only be set in the compilation environment (/removeintchecks).
Imports
Imports makes names available without qualification for the namespace members of the file. There are three forms, and one statement can hold several clauses separated by commas.
| Form | Example | Meaning |
|---|---|---|
| namespace or type members | Imports System.Text | the types of the namespace (or the shared members of the type) can be used by their simple names |
| alias | Imports IO = System.IO | a short name for a namespace or a type; an alias cannot refer to another alias of the same file |
| XML namespace | Imports <xmlns:db="http://example.com/db"> | a prefix (or the default namespace, <xmlns="…">) for XML literals and XML member access |
The names in an Imports statement are read as fully qualified from the global namespace (so Imports System always means the .NET namespace, even if the file declares a class called System). The scope of the imports is the namespace members of that file only, never other files. The compiler can also add implicit imports for the whole project (the <Import Include="…"> items of the project file; the default templates import a handful of System namespaces).
Namespaces
A namespace is open-ended: any number of declarations in any number of files add to it. A qualified name is a shorthand for nesting, and Global names the root regardless of the project’s root namespace.
Namespace Shop.Billing ' same as Namespace Shop, then Namespace Billing inside it
Public Class Invoice
End Class
End Namespace
Namespace Global.Elsewhere ' Elsewhere in the true global namespace
Public Class Thing
End Class
End Namespace
Namespace Global (alone) and Namespace Global.Name. The last two cannot be nested inside another namespace.The entry point
A program starts in a shared method called Main, not generic, not Async, with one of four signatures. Its accessibility does not matter. If a project has more than one, the project names the startup object; for Windows Forms projects the compiler can generate the entry point (the application framework).
Sub Main()
Sub Main(args() As String)
Function Main() As Integer
Function Main(args() As String) As Integer
Files that make one project
- Partial types. A class, structure, interface or module marked
Partialcan be written in several files; the designer-generated half is usuallyForm1.Designer.vbbesideForm1.vb(see classes). - Generated files. The build writes
AssemblyInfoand attribute files intoobj/; they begin with a comment block that says<auto-generated>, repeatOption StrictandOption Explicitand list the assembly attributes. Older projects keep their ownAssemblyInfo.vb(orMy Project\AssemblyInfo.vb) with<Assembly: …>lines. - The project. A
.vbproj(MSBuild XML) lists compiler settings, references and, in old-style projects, every source file; SDK-style projects include**/*.vbby default. See tooling. - Resources. Forms and settings have a
.resxXML file beside them; designer files are plain Visual Basic.
Encoding and line endings
The compiler reads UTF-8 (with or without a byte order mark) and UTF-16 with a mark, and otherwise the code page given with /codepage or the system default, which is why old files are often Windows-1252. Visual Studio writes UTF-8 with a mark and CR LF line ends by default. The language treats CR, LF, CR LF, U+2028 and U+2029 as line terminators (Roslyn also reads U+0085); the space characters of the Unicode space class and the tab are white space. The viewer shows a file that is not valid UTF-8 as Windows-1252.
Not described
Known, not yet covered
- Reference: the default values of the Option statements for each project template and compiler version, the exact list of implicit imports of each template, and the compiler options of
vbcare not listed in full (see tooling). - Reference: the application framework (
My.Application, the generatedApplication.Designer.vb) and ASP.NET code-behind files are not described.
See also
- Lexical structure – comments, names, literals and line continuation
- Classes, modules and interfaces – what the namespace members are
- Preprocessing directives –
#If,#Regionand the other#lines