VB.NET Syntax and Project Setup
Before you start
You need: basic programming ideas — variables, conditions, loops. C# from Track 03 helps but is not required; this article explains the differences as they appear.
You need installed: Visual Studio with the .NET desktop development workload.
Time: about 45 minutes, plus the practice.
Learning objective
Open an existing VB.NET project, understand what its compiler options change, and read declarations, types, and operators without guessing.
Topics
- Why VB.NET applications still run in production
- .NET Framework versus modern .NET
- Creating and opening a VB.NET project in Visual Studio
Option Strict,Option Explicit, andOption InferDim, value and reference types,Nothing- Strings, concatenation, and comparison
- Operators and their C# equivalents
Why this track exists
A large amount of working business software was written in VB.NET between 2002 and roughly 2015: internal admin tools, reporting utilities, Web Forms applications, Office add-ins. That software still processes real transactions, so companies still pay people to maintain it.
You are unlikely to start a new project in VB.NET. You are quite likely, as a fresher, to be handed one and asked why a screen is wrong. The goal here is reading fluency and safe change, not building from scratch.
VB.NET and C# compile to the same intermediate language and use the same base class library. List(Of T) in VB.NET is List<T> in C#. The concepts transfer; the syntax is what stops people.
.NET Framework versus modern .NET
Most legacy VB.NET runs on .NET Framework (4.6.x, 4.7.x, 4.8), which is Windows-only and installed as part of the operating system. Modern .NET supports VB.NET for console and class-library projects, but not for Web Forms or WinForms designers in the same way.
Check .vbproj before assuming anything:
<!-- .NET Framework: old-style project, verbose, lists every file -->
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<!-- Modern .NET: SDK-style project, short -->
<TargetFramework>net8.0</TargetFramework>
An old-style .vbproj that lists every source file individually tells you the project predates 2017 tooling. That is useful context before you propose changes.
Opening a VB.NET project in Visual Studio
You will almost always be handed an existing solution rather than starting one.
- File → Open → Project/Solution, and pick the
.sln. - If a dialog offers to retarget or upgrade the project, say no the first time. Build it as it is, so you learn whether it was working before you touched anything.
- Build → Build Solution (
Ctrl+Shift+B) and read the Error List before anything else. - Press
F5to run, orCtrl+F5for a console project.
If the project will not load at all, Solution Explorer shows it as unavailable and the reason is usually one of three things:
| Symptom | Cause | Fix |
|---|---|---|
| "The project requires .NET Framework 4.x which is not installed" | That targeting pack is missing | Visual Studio Installer → Individual components → tick the pack |
| Project shows as unavailable / load failed | Missing workload | Add .NET desktop development, and ASP.NET and web development for Web Forms |
| Hundreds of errors about missing types | NuGet packages not restored | Right-click the solution → Restore NuGet Packages, then rebuild |
Read the compiler options before reading the code. They are not only at the top of a file — the project-wide defaults live in right-click the project → Properties → Compile:
| Setting | Where | Why it matters |
|---|---|---|
| Option Strict | Properties → Compile | Off is the default and hides conversion bugs until run time |
| Option Explicit | Properties → Compile | On everywhere sane |
| Option Infer | Properties → Compile | Affects what Dim x = 5 means |
| Target framework | Properties → Application | Tells you which .NET this is |
A file-level Option Strict On overrides the project setting for that file only. So one file can be strict inside an otherwise loose project — which is exactly how a team migrates gradually, and why two files can behave differently for no visible reason.
Never "fix" all the warnings the day you arrive. Turning Option Strict On across an old project can produce thousands of errors. Read first; change one thing at a time.
Compiler options — read these first
Three Option settings change what the compiler allows. They appear at the top of a file or in project properties, and they explain most of the surprising code you will meet.
| Option | On means | Default |
|---|---|---|
Option Explicit | Every variable must be declared | On |
Option Strict | No implicit narrowing conversions; no late binding | Off |
Option Infer | Dim x = 5 infers Integer | On |
Option Explicit On
Option Strict On
Option Infer On
Option Strict Off is the default and is the single biggest source of legacy bugs. With it off, this compiles:
' Option Strict Off — compiles, fails at run time if the text is not a number
Dim marks As Integer
marks = txtMarks.Text
With Option Strict On, that is a compile error and you are forced to write the conversion you meant:
Option Strict On
Dim marks As Integer
If Not Integer.TryParse(txtMarks.Text, marks) Then
ShowError("Marks must be a whole number.")
Return
End If
Turning Option Strict On in an old project usually produces hundreds of errors at once. Do not do it as a casual improvement — it is a planned piece of work, file by file, with testing.
Declarations and types
Dim declares. The type follows the name after As.
Dim studentName As String = "Ravi Kumar"
Dim rollNumber As String = "NCA-2024-0012"
Dim marksObtained As Integer = 87
Dim feeBalance As Decimal = 8000D
Dim isActive As Boolean = True
Dim admittedOn As Date = New Date(2024, 6, 15)
Value types (Integer, Decimal, Boolean, Date, Structure) hold their value directly. Reference types (String, arrays, class instances) hold a reference. Nothing is VB.NET's null, but it also means "the default value" for a value type — assigning Nothing to an Integer gives 0, not an error.
Dim count As Integer = Nothing ' count is 0
Dim name As String = Nothing ' name is a null reference
Use Decimal for money. Double introduces rounding error that shows up in fee totals.
Constants are locals or members fixed at compile time; ReadOnly is a field modifier fixed at construction:
Const MaxMarks As Integer = 100
Private ReadOnly _schoolCode As String = "NCA"
ReadOnly is not valid on a local variable — it appears only on class and structure fields.
Strings
VB.NET uses & for concatenation. + also works on strings, which is exactly why you should not use it — with Option Strict Off, "5" + 3 silently produces 8.
Dim label As String = studentName & " (" & rollNumber & ")"
Comparison is by value with =, unlike C#'s == on references:
If studentName = "Ravi Kumar" Then
' true when the text matches
End If
For case-insensitive comparison, be explicit rather than lowering both sides:
If String.Equals(section, "a", StringComparison.OrdinalIgnoreCase) Then
Other regular arrivals in legacy code:
Dim trimmed As String = studentName.Trim()
Dim upper As String = studentName.ToUpper()
Dim isEmpty As Boolean = String.IsNullOrWhiteSpace(studentName)
Dim parts() As String = rollNumber.Split("-"c)
The "-"c suffix makes a Char rather than a String. Legacy code often uses Split("-"), which works but is a different overload.
Operators
| VB.NET | C# | Note |
|---|---|---|
= | == or = | Assignment and comparison, decided by context |
<> | != | Not equal |
And / Or | & / | | Always evaluates both sides |
AndAlso / OrElse | && / || | Short-circuits |
Not | ! | Negation |
& | + | String concatenation |
\ | / on integers | Integer division |
Mod | % | Remainder |
^ | Math.Pow | Exponent |
Is / IsNot | == / != on references | Reference identity |
The And versus AndAlso distinction matters and is covered in the next article — And evaluates the right side even when the left is already False, which will throw on a null reference.
Comments and line continuation
' Single quote starts a comment
REM This also works and appears in very old code
Dim total As Decimal = feeAccount.TotalFees -
feeAccount.PaidAmount -
feeAccount.DiscountAmount
Modern VB.NET allows implicit line continuation after an operator. Pre-2010 code uses a trailing underscore instead, which you will still see:
Dim total As Decimal = feeAccount.TotalFees _
- feeAccount.PaidAmount
Errors you will hit
| Message | Cause | Fix |
|---|---|---|
BC30451: '<name>' is not declared. It may be inaccessible due to its protection level | Typo, or the file is not in the project | Check the spelling and Solution Explorer |
BC30512: Option Strict On disallows implicit conversions from 'String' to 'Integer' | Assigned text to a number with strict on | Integer.TryParse it |
BC42104: Variable is used before it has been assigned a value | Declared but never set | Assign it at the declaration |
BC30203: Identifier expected | Usually a stray line-continuation _ or a broken statement | Check the previous line |
| The project will not load | Missing targeting pack or workload | See the table above |
| Two files behave differently for no reason | One has a file-level Option Strict On | Check the top of each file |
BC30512 is a good error. It is Option Strict On catching at compile time what would otherwise have been a run-time crash in front of a user.
Common mistakes
- Assuming
Option StrictisOn— it isOffby default, and a string assigned to anIntegerwill compile - Turning
Option Strict Onacross an old project in one commit - Using
Doublefor fee and payment amounts - Using
+to join strings, which changes meaning underOption Strict Off - Reading
=as assignment inside anIf, where it is comparison - Assuming
Nothingbehaves likenullfor value types - Editing a
.vbprojby hand without noticing it is an old-style project file
Practice
Open any existing VB.NET project. Record its target framework, whether Option Strict is on, and how many files declare their own Option lines. Then find one variable assignment that would fail to compile if Option Strict were turned on, and write the explicit conversion it would need.
You can now
- Open an existing VB.NET solution and build it
- Find
Option Strictin both the file and the project properties - Say why
Option Strict Offis the biggest source of legacy bugs - Read VB.NET declarations, strings and operators without translating to C# first
- Tell .NET Framework from modern .NET, and say which you are looking at
- Diagnose a project that will not load
Review questions
- What does
Option Strict Offpermit thatOnforbids, and why does it matter in production? - Which type should hold a fee amount, and why not
Double? - What is the difference between
AndandAndAlso? - What does assigning
Nothingto anIntegerproduce?
Next: Conditions and loops