Home > Articles > Programming > Windows Programming

The Anatomy of a Visual Basic Project

  • Print
  • + Share This
Although you can create lots of kinds of projects both for Windows and the Web with Visual Basic 2010, there is a common set of files for each project. In this chapter you learn which files give the structure to each project and how the files influence the building of an application. You also get an overview of references, namespaces, classes, modules, and Visual Basic keywords.
This chapter is from the book

This chapter is from the book


  • Brief Overview of Types and Members
  • Visual Basic 2010 Reserved Keywords
  • Understanding Project Files
  • Understanding References

Brief Overview of Types and Members

In the second part of this book, we discuss important topics related to the object-oriented programming with Visual Basic 2010, and we explore features such as types, classes, modules, namespaces, interfaces, and class members. Before going into this, it would be a good idea to have at least an overview of classes, modules, namespaces, and class members because you will find these objects in code examples or in Visual Basic features that are shown prior to Chapter 7, "Class Fundamentals."


Classes in .NET development represent objects whose declaration is enclosed within Class..End Class blocks. The following is an example of class declaration:

Class Person
End Class

Classes are reference types (explained more in Chapter 4) and can expose members that influence the object's behavior, such as properties and methods. Classes can implement interfaces and they can also be static (or Shared according to the VB terminology) and can provide support for inheritance.


Properties are characteristics of a type. For example, the previously shown class Person could have two properties, such as the first name and the last name:

Class Person
  Property FirstName As String
  Property LastName As String
End Class


Methods are the .NET representation of what in other programming environments you define as functions and procedures. A method can be a member of classes, structures, and modules. Methods that return a value are represented by Function..End Function blocks, such as the following:

Function DoSomething() As String
      Return "A text message"
End Function

Methods that do not return a value are represented by Sub..End Sub blocks, such as the following:

Sub DoSomething()
'write your code here
End Sub

Methods can receive parameters that can be processed within code blocks. Such parameters are called, using .NET terminology, arguments. The following code block shows an example of an argument named message:

Sub DoSomething(ByVal message As String)
End Sub


Modules are defined within a Module..End Module code block. Modules are basically Shared classes but, unlike classes, they cannot implement interfaces. The following is an example of a module:

Module Module1

    Sub DoSomething()
        'Code goes here
    End Sub
End Module

Members defined inside modules don't require the name of the module when invoked.


Structures are .NET objects represented by a Structure..End Structure code block. Structures are value types, which are described more in Chapter 4, and for classes, can expose properties, methods, and so on. The following is an example of a structure declaration:

Structure SomeValues

    Property FirstValue As Boolean
    Property SecondValue As Integer

    Sub DoSomething()

    End Sub
End Structure


Inheritance is one of the most important features of the .NET Framework. A class can inherit or derive from another class, meaning that the new class can have all properties, methods, and members exposed by the first class, which is called base class, and can then define its own members. Inherited members can then be overridden to adapt their behavior to the new class' context. The .NET Framework provides one-level inheritance, meaning that a class can inherit from one other class per time. Each class derives implicitly from System.Object. The Inherits keyword is used to inherit classes. The following code provides an example of a base class named Person and of a derived class named Customer:

Public Class Person
    Public Property FirstName As String
    Public Property LastName As String

    'A new definition of System.Object.ToString
    Public Overrides Function ToString() As String
        Return String.Concat(FirstName, " ", LastName)
    End Function
End Class

Public Class Customer
    Inherits Person

    Public Property CompanyName As String

    Public Overrides Function ToString() As String
        Return CompanyName
    End Function

End Class

In the preceding example the Person class overrides (that is, provides a new definition of) the System.Object.ToString method. The Customer class exposes a new CompanyName property whereas, via inheritance, it exposes the FirstName and LastName properties. Finally, the class also overrides the Person.ToString method. Inheritance is discussed in Chapter 12. "Inheritance."


A namespace is basically a container of types. This means that one namespace can contain multiple classes, multiple modules, multiple interfaces, multiple structures, and so on. The following is an example of a namespace exposing two classes, one module, one structure, and one interface:

Namespace Test

    Class Person
        Property FirstName As String
        Property LastName As String
    End Class

    Class Employee
        Inherits Person

        Property EmployeeID As Integer
    End Class

    Module Module1

        Sub DoSomething()

        End Sub
    End Module

    Interface ITest
        Sub TakeATest()
    End Interface

    Structure SomeValues
        Property FirstValue As Boolean
        Property SecondValue As Integer
    End Structure
End Namespace

Namespaces are important for a better organization of types, but there is another reason. You could have two classes with the same name (for example, Employee) but with different properties. Namespaces enable you to avoid conflicts in such scenarios. You can access types exposed by a namespace by simply writing its identifier followed by a dot and then by the type name. For example, if you want to invoke the method DoSomething in Module1 you could write the following line of code:


Namespaces are described in detail in Chapter 9, "Organizing Types Within Namespaces."

Accessing Members

Unless you declare shared objects, you need to instantiate classes and structures before you can use members and store information within those objects. You instantiate a class declaring a variable and using the New keyword as in the following line of code:

Dim testPerson As New Person

Then you can set properties for the new instance or eventually invoke other members such as methods. For example, you could initialize testPerson's properties as follows:

testPerson.FirstName = "Alessandro"
testPerson.LastName = "Del Sole"

Basically when you need to invoke a member of a class, you type the name of the instance (in this example testPerson) followed by a dot and by the name of the member. For shared members, you just write the name of the class or structure followed by a dot and by the name of the member.

Imports Directives

As we saw before, namespaces can expose objects that expose members. Moreover, namespaces can expose nested namespaces, exposing objects and so on. You often need to access members of objects exposed by nested namespaces. To avoid the need of typing the entire name of long (or nested) namespaces and writing long lines of code, the Visual Basic language offers the Imports directive. For example, consider the following lines of code that open a file on disk:

Dim myFile As New System.IO.FileStream("C:\test.bin",


The FileStream class is exposed by the IO namespace that is exposed by the System namespace. You could place the following directive at the beginning of the code:

Imports System.IO

At this point the first line of code could be rewritten as follows:

Dim myFile As New FileStream("C:\test.bin", FileMode.Open)

Imports directives are useful because they help to handle a much clearer code. Just remember that such directives must be the first lines of each code file. The only exception is constituted by the Option clause that must precede the Imports directives.

#Region..#End Region Directives

Visual Basic provides an efficient way for organizing your code within regions. A region represents a collapsible area of the code editor that can contain any code and that takes the advantage of the outlining feature of the Visual Studio 2010 code editor. Regions are defined with #Region..#End Region directives. The following code snippet shows how to define a region:

#Region "Private Members"

    Private firstItem As String
    Private secondItem As Integer

#End Region

The #Region directive requires the specification of a descriptive caption. When you declare regions, you can then collapse regions by clicking on the - (minus) symbol on the left of the #Region directive. When collapsed, the region shows just the descriptive caption and can then be expanded again by clicking on the + (plus) symbol. Also notice that the Visual Studio 2010 IDE allows collapsing a region by double-clicking anywhere on the #Region..#End Region connector line on the left side of the code window. Such directives will not be compiled and will not affect performances at all.


Attributes are classes deriving from the System.Attribute class and provide declarative information to objects or members they are applied to, providing also the ability to change their behavior. As a convention, applying an attribute is also known as decorating or marking a member. Attributes are basically class instances; you can apply attributes enclosing their names within < > symbols; moreover they can receive arguments. The following are examples of decorating members with attributes:

<Serializable()> Class Test

End Class

<CLSCompliant(True)> Class Test

End Class

In the preceding snippets, the Serializable attribute creates a new instance of the System.SerializableAttribute class that indicates to the compiler that the decorated class can take advantage of the serialization process. The CLSCompliant attribute, whose value is True, means that the decorated class is compliant to Microsoft's Common Language Specifications. Attributes are discussed in Chapter 48, "Coding Attributes," and you often find examples in this book that require code to be decorated with attributes.

A New Feature: Implicit Line Continuation

Visual Basic 2010 introduces an important new feature when writing code (which is a historical change in the language) known as implicit line continuation. Back in older versions, if you needed to split a long line of code into more brief and readable lines of code in the editor, you needed to add an underscore ( _ ) character. With Visual Basic 2010 this is no longer necessary, with a few exceptions. You can simply press Enter when you need to split a line of code, and the compiler will automatically recognize a line continuation, depending on what kind of code you are writing.

The following are situations in which the implicit line continuation is allowed:

  • Within LINQ queries
  • Within embedded expressions in LINQ to XML queries
  • After dots
  • After commas
  • After brackets
  • When decorating members with attributes
  • Before an assignment

Let's see how implicit line continuation works. The first code snippet shows a LINQ query:

Dim query = From proc In Process.GetProcesses.AsEnumerable
            Where (proc.ProcessName.StartsWith("A"))
            Select proc

In Visual Basic 2008 you needed to add an underscore after the first and second line of code. Now this is no longer necessary. The second code snippet shows a LINQ to Xml query with embedded expressions without underscores:

Dim doc = <?xml version="1.0"?>
            <%= From proc In query
              Select <Process>
                             <Name <%= proc.ProcessName %>/>

The third code snippet shows both commas and brackets without underscores:

Dim p As New List(Of Integer) From {

The fourth code snippet is about dots. In this case implicit line continuation can be useful when invoking methods or properties:

Dim appDataDir As String = My.Computer.FileSystem.

The fifth code snippet shows implicit line continuation with attributes:

Class Test

End Class

The sixth and last code snippet demonstrates how you can use implicit line continuation before an assignment:

Dim aValue As Integer
aValue =

All the preceding code snippets are now perfectly legal. In all cases of the preceding examples, implicit line continuation is not allowed. For example, you still must add an underscore after the Handles clause when handling events:

Private Sub AnEventHandler(ByVal sender As Object, ByVal e As EventArgs) _
                           Handles anObject.Disposed

End Sub

Although you might expect such discussion in Chapter 2, "Getting Started with the Visual Studio 2010 IDE," about the code editor, you first need to get an overview of concepts that help you understand where implicit line continuation is allowed or disallowed.

  • + Share This
  • 🔖 Save To Your Account