Structure (Code Organization)
for Visual Basic .net

A complex (that is, any program bigger than Hello, World) VB.net program is composed of classes and modules.  A number of classes and modules are supplied with the FCL (Framework Class Library), but you can create and use others too.  A Module is a collection of procedures, variables, and constants.

Classes also have variables and constants (known as the class' properties) and procedures (known as the class' methods).  In fact each type of control such as Label or TextBox is actually a class.  When you add such a control to your project, you create an instance (an object) of that class.  (The properties and methods for a class are collectively called a class' members.)

Keep in mind that classes are also objects, which is why you can use code such as:

Color.RED
Convert.ToDouble( myNum )

instead of:

Dim myColor = new Color()
myColor.RED
Dim myConvert = new Convert()
myConvert.ToDouble( myNum )

VB.net supports different types of procedures:

There are also event handlers, a type of Sub procedure that gets invoked automatically when some event occurs (such as a form loading or the user clicking or typing).  Usually the term procedure in VB.net means either Sub or Function.

Procedures in VB.net must be either methods of a class or contained in modules.  You can also group a collection of modules and classes into a namespace, which helps you organize your code and control the use and visibility (scope) of things.  (So for example, two programmers don't name the same class Foo.)  Namespaces can be nested and thus arranged in a hierarchy.

A VB.net program could be defined as one or more namespaces, each containing one or more classes and/or modules, each of which contains one or more procedures and/or variables and constants.  So a .vb source code file might look like this:

Namespace MyNameSpace
    Module Module1
        Dim foo As Integer = 10
        Const MAX As Integer = 10

        Sub Main()
            Console.WriteLine("Hello, World!")
        End Sub 'Main

        Function Sum(ByVal num1 As Integer, ByVal num2 As Integer) As Integer
            Return num1 + num2
        End Function 'Sum
    End Module 'Module1

    Module Module2
        ' ...
    End Module 'Module2

    Class Class1
        Const FOO As Integer = 100
        Dim Bar As Integer

        Sub Sub1()
           ' do something such as pop up a window, read a file, ...
        End Sub 'Sub1

        Function Square(ByVal num As Integer) As Integer
            Return num * num
        End Function 'Square
    End Class 'Class1
End Namespace 'MyNameSpace

Qualified Names

Variable, constant, and procedure names only have to be unique within their module or class.  Module and class names only have to be unique within their namespace.  This is because names can be qualified with their namespace and module or class names.  For example the Function Sum above has the fully qualified name of MyNameSpace.Module1.Sum.  It is only fully qualified names that must be unique.

You can use the unqualified name from within the same module or class, or a partially qualified name from within the same namespace.  You can also use Using statements to avoid having to qualify names from outside the current module or class.

By default all your modules and classes are put into an automatically created namespace, named for the project.  This is sometimes also referred to as the root namespace.  All the FCL classes and modules are in the System namespace.

In general a VB.net project puts one class or module per source code (.vb) file.

If you look at the code for some project you've built, you'll see all the code you're written appears in one or another Sub procedure, which are members of a class named for the form.

Really big programs may consist of several projects designed to work together.  These collections of projects (and resources) are called assemblies.


Overloading Procedures

Although it is true that fully qualified names must be unique, there appears to be an exception to this rule.  Procedure names are mangled by the compiler.  The resulting name includes information about the number, type, and order of any parameters declared (this is called a parameter profile).  The procedure name plus its parameter profile are together known as a procedure signature.  It is procedure signatures that must be unique, not procedure names.

Only procedures can be overloaded.  The concept doesn't apply to properties.

For example:

Public Class Form1
Function Add(ByVal num1, ByVal num2 As Integer) As Integer
     Return num1 + num2
End Function

Function Add(ByVal num1, ByVal num2, ByVal num3 As Integer) As Integer
    Return num1 + num2
End Function

Function Add(ByVal num1, ByVal num2 As Decimal) As Decimal
    Return num1 + num2
End Function
End Class

While the exact way procedure names are mangled isn't defined, it might be something like this for these three procedures:

Add_I_I
Add_I_I_I
Add_D_D

When you invoked a procedure in your code, the system determines which procedure to use by matching the procedure call to the mangled names:

Add(2I, 2I)     ' Add_I_I
Add(1I, 2I, 3I) ' Add_I_I_I
Add(3.5D, 3.5D) ' Add_D_D

The procedure name Add appears to be duplicated in the class.  This is called procedure overloading (you are overloading the procedure name with multiple meanings).  Many standard classes in VB.net have overloaded procedures.

Using Visual Studio, when entering a procedure that is overloaded, the tool-tip that appears will show all the different procedures with that name (look for the tiny scroll arrows).  See MessageBox.Show for an example.