Anatomy of a VB.NET file
VB.NET is a modern, object-oriented programming language in the .NET family, known for its readable, English-like syntax.
File extensions: .vb
Every part of the example below is labelled and explained. This page is one of 55 annotated tours on AnatomyOf, a free, open-source project by LunarWerx Studios.
What is inside a VB.NET file
Comment
Single-line ('), ignored by the compiler.
A comment starts with an apostrophe (') and runs to the end of the line; the compiler discards everything after it. There is no dedicated block-comment syntax. A multi-line explanation just means prefixing every line with its own apostrophe, which is very on-brand for a language descended from BASIC's REM statement. The legacy keyword REM still works as a comment marker for historical compatibility, but essentially no VB.NET code written this century uses it; the apostrophe is the idiomatic form in every style guide and every IDE snippet.
Imports statement
Imports namespaces to use their types without full qualification.
Imports System brings every public type in the System namespace into scope, so the rest of the file can write Console.WriteLine instead of System.Console.WriteLine. Imports are conventionally listed at the very top of the file, before any namespace or module declaration. A project can also declare project-level imports in its .vbproj file, which apply implicitly to every source file without an explicit Imports line: useful for namespaces like System.Linq that nearly every file in a project ends up needing.
Namespace declaration
Organizes code into logical groups.
A Namespace block groups related types under a dotted name, such as MyConsoleApp, so that two types named the same thing can coexist as long as they live in different namespaces. Namespaces are purely organizational and, like in C#, need not match the file or folder layout on disk. Unlike a Module or Class block, a Namespace cannot itself hold executable code or fields directly. It only contains further type declarations, closed with a matching End Namespace.
Module / Class definition
A container for code, data, and methods.
A Module is a VB.NET-specific construct: a container whose members are implicitly Shared (static), so nothing inside it ever needs an instance created with New. Console applications traditionally put Sub Main inside a Module precisely because the entry point must be callable without instantiating anything first. A Class is the general-purpose, instantiable alternative, supporting fields, properties, constructors, and inheritance. Both are closed with their own matching End Module / End Class, and a single file may declare several of either.
Variable declaration (Dim/Const)
Declares variables (Dim) and constants (Const).
Dim greeting As String = "Hello, VB.NET!" declares a variable with an explicit type using the As clause. With Option Strict On (recommended in every project template since VB 2005), the compiler enforces that type and disallows silent narrowing conversions; without it, VB.NET quietly falls back to its dynamically-typed Variant-like heritage, for better or worse. Const MaxCount As Integer = 3 declares a compile-time constant that cannot be reassigned. Unlike Dim, a Const must be initialized at declaration and its value must be resolvable at compile time: no calling a function to produce it.
Subroutine definition (Sub)
Defines a procedure that does not return a value.
Sub declares a procedure with no return value, the VB.NET equivalent of a void method. Sub Main(args As String()) is the conventional entry point for a console application, discovered by the .NET runtime the same way Main is in C#. A Sub is invoked as a statement on its own line, never as part of an expression, since it produces nothing to use. Every Sub block closes with End Sub, and like most VB.NET block keywords this pairing is enforced by the compiler, not just a style convention.
Function definition
Defines a procedure that returns a value.
Function Add(a As Integer, b As Integer) As Integer declares a procedure whose trailing As Integer names its return type, and whose body must produce that type via a Return statement (or, in older style, by assigning the function's own name as if it were a variable). End Function closes the block. Functions and Subs together are called "procedures" in VB.NET terminology, and both support optional parameters (with default values), ByRef vs ByVal parameter passing, and overloading via the Overloads modifier.
Method call
Executing a subroutine or function.
Console.WriteLine(greeting) calls the shared WriteLine method on the Console class, passing greeting as its argument. Parentheses around arguments are required when calling a Function for its value, and are conventional (though technically optional in some Sub call forms) for readability. VB.NET resolves overloaded calls by matching argument types at compile time, the same way C# does, and supports named arguments (WriteLine(value:=greeting)) so a caller can label which parameter each argument fills.
Control flow (loop)
Executes code repeatedly (For, While).
For i As Integer = 1 To MaxCount ... Next counts a loop variable through an inclusive range, optionally with a Step clause to change the increment. For Each element In collection iterates any IEnumerable, and While/Do While/Do Until loops repeat based on a condition checked before or after the body. Every loop form is closed by its own matching keyword (Next, End While, Loop), which is part of why VB.NET reads as unusually verbose next to brace languages: but it also means a stray closing brace can never silently close the wrong block.
Control flow (conditional)
Selects which code to execute based on a condition (If, Select Case).
If ... Then ... Else ... End If routes execution based on a Boolean condition. The single-line form (If x Then y) omits End If entirely, while the block form spanning multiple lines requires it, a frequent source of confusion for newcomers copy-pasting snippets between the two styles. Select Case handles multi-branch dispatch more cleanly than a chain of ElseIfs, supporting single values, ranges (Case 1 To 5), and comma-separated lists (Case 1, 3, 5) per Case clause.
String interpolation ($"...")
Embeds expressions in double-quoted strings.
Prefixing a string literal with $, as in $"Even count: {i}", lets any expression inside { } be evaluated and formatted directly into the resulting string. It was introduced in VB 14 (Visual Studio 2015), years after classic VB6-style concatenation with & had already calcified into muscle memory for a generation of developers. A literal brace inside an interpolated string is escaped by doubling it ({{ / }}), and format specifiers work the same as with String.Format, e.g. $"{price:C}" for currency formatting.
Official VB.NET site · All languages on AnatomyOf
The interactive tour needs JavaScript. Enable it to hover a callout and trace it into the code.