Visual Studio defines an enormous number of variables, classes, routines, and other entities to provide tools for your applications. It categorizes them in namespaces to prevent name collisions and to make it easier for you to find the items you need.
The Visual Studio root namespaces are named Microsoft and System. The Microsoft namespace includes the CSharp, JScript, VisualBasic, and Vsa namespaces that support different programming languages. The Microsoft namespace also includes the Win32 namespace, which provides classes that handle operating system events and that manipulate the registry.
The System namespace contains a huge number of useful programming items, including many nested namespaces. For example, the System.Drawing namespace contains classes related to drawing, System.Data contains classes related to databases, System.Threading holds classes dealing with multithreading, and System.Security includes classes for working with security and cryptography.
Note that these namespaces are not necessarily available to your program at all times. For example, by default, the Microsoft.JScript namespace is not available to Visual Basic programs. To use it, you must first add a reference to the Microsoft.JScript.dll library.
Visual Studio includes so many programming tools that the namespace hierarchy is truly enormous. Namespaces are refined into subnamespaces, which may be further broken into more namespaces until they reach a manageable size. Although this makes it easier to differentiate among all of the different programming entities, it makes the fully qualified names of some classes rather cumbersome.
For example, the following code draws a rectangle inside a form. Fully qualified names such as System .Drawing.Drawing2D.DashStyle.DashDotDot are so long that they make the code hard to read.
Private Sub DrawDashedBox(ByVal gr As System.Drawing.Graphics) Dim my_pen As New System.Drawing.Pen(System.Drawing.Color.Blue, 5) my_pen.DashStyle = System.Drawing.Drawing2D.DashStyle.DashDotDot Dim rect As System.Drawing.Rectangle = Me.ClientRectangle rect.X += 10 rect.Y += 10 rect.Width -= 20 rect.Height -= 20 gr.Clear(Me.BackColor) gr.DrawRectangle(my_pen, rect) End Sub
You can use the Imports statement at the top of the file to make using namespaces easier. After you import a namespace, your code can use the items it contains without specifying the namespace.
The following version of the previous code imports the System.Drawing and System.Drawing.Drawing2D namespaces, so it doesn’t need to mention the namespaces in its object declarations. This version is much easier to read.
Imports System.Drawing Imports System.Drawing.Drawing2D ... Private Sub DrawDashedBox(ByVal gr As Graphics) Dim my_pen As New Pen(Color.Blue, 5) my_pen.DashStyle = DashStyle.DashDotDot Dim rect As Rectangle = Me.ClientRectangle rect.X += 10 rect.Y += 10 rect.Width -= 20 rect.Height -= 20 gr.Clear(Me.BackColor) gr.DrawRectangle(my_pen, rect) End Sub
Figure 17-1 shows the results.
Figure 17-1: The Imports statement greatly simplifies the code that draws this dashed rectangle.
A file can include any number of Imports statements. The statements must appear at the beginning of the file, and they define namespace shortcuts for the entire file. If you want different pieces of code to use different sets of Imports statements, you must place the pieces of code in different files. If the pieces of code are in the same class, use the Partial keyword so you can split the class into several files.
If a program imports more than one namespace that defines the same class, it must use fully qualified names to select the right versions. For example, suppose that the Payroll and HumanResources modules both define Employee classes. Then you must use the fully qualified names Payroll.Employee and HumanResources.Employee to differentiate between the two.
The complete syntax for the Imports statement is as follows:
Imports [alias =] namespace[.element]
The following sections describe namespace aliases and elements in detail.
Visual Basic lets you quickly import a namespace for all of the modules in a project. In Solution Explorer, double-click My Project. Click the References tab to display the page shown in Figure 17-2.
Figure 17-2: Use the My Project References tab to import namespaces for every module in a project.
In the Imported Namespaces list at the bottom, select the check box next to the namespaces that you want to import. The program’s files will be able to use the objects defined in these namespaces, even though they do not include Imports statements.
This is most useful when most of the program’s modules need to import the same namespaces. Including the Imports statement in the files makes it easier for developers to see which namespaces are available, however, so you might want to do this instead, particularly if you use unusual namespaces.
By default, Visual Basic loads imports for the type of application you are building. For example, when you start a Windows form application, Visual Basic imports the following namespaces:
Microsoft.VisualBasic
System
System.Collections
System.Collections.Generic
System.Drawing
System.Diagnostics
System.Windows.Forms
You can use the upper half of the References property page to manage project references. Use the Add and Remove buttons (scrolled off to the right in Figure 17-2) to add and remove references.
Click the Unused References button (scrolled off to the right in Figure 17-2) to see a list of referenced libraries not currently used by the project. Before you distribute the program, you can remove the unused references.
You can use the alias clause to define a shorthand notation for the namespace. For instance, the following code imports the System.Drawing.Drawing2D namespace and gives it the alias D2. Later, it uses D2 as shorthand for the fully qualified namespace.
Imports D2 = System.Drawing.Drawing2D ... Dim dash_style As D2.DashStyle = D2.DashStyle.DashDotDot
An Imports statement with an alias is more restrictive than an Imports statement without one. The previous code defines a namespace alias, so the code must use the alias to access the namespace. On one hand, if you remove the occurrences of D2 from the declaration of the dash_style variable, Visual Basic will not understand what the DashStype type and the DashStyle.DashDotDot value mean. On the other hand, if you omit the alias from the Imports statement, the previous code works without the occurrences of D2.
You can get the best of both worlds by importing the namespace twice, once with an alias and once without. The following code imports the System.Drawing.Drawing2D namespace twice. In the declaration of the variable dash_style, the variable’s type DashStyle does not use the namespace alias, but the initialization value D2.DashStyle.DashDotDot does.
Imports System.Drawing.Drawing2D Imports D2 = System.Drawing.Drawing2D ... Dim dash_style As DashStyle = D2.DashStyle.DashDotDot
This technique is handy if you need to use two namespaces that define different classes with the same name. Normally, if two namespaces define classes with the same name, you must use the fully qualified class names so that Visual Basic can tell them apart. You can use aliases to indicate the namespaces more concisely.
Suppose that the JobClasses and FinanceStuff namespaces both define an Employee class. If you declare a variable using the unqualified class Employee, Visual Basic would not know which version to use. The following code shows how you can declare fully qualified versions of the Employee class:
Imports MyApplication.JobClasses Imports MyApplication.FinanceStuff ... Dim job_emp As MyApplication.JobClasses.Employee Dim finance_emp As MyApplication.FinanceStuff.Employee ...
You can use aliases to simplify these declarations. You could use Job as an alias for MyApplication .JobClasses and Finance as an alias for MyApplication.FinanceStuff.
Now suppose that the JobClasses namespace also defines the Dispatcher class. The FinanceStuff namespace does not define a Dispatcher class, so there is no name conflict between the namespaces. You could use the Job alias to refer to the Dispatcher class, or you could import the JobClasses namespace again without an alias as shown in the following code:
Imports MyApplication.JobClasses Imports Job = MyApplication.JobClasses Imports Finance = MyApplication.FinanceStuff ... Dim job_emp As Job.Employee Dim finance_emp As Finance.Employee Dim job_dispatcher As Dispatcher ...
In addition to importing a namespace, you can import an element within the namespace. This is particularly useful for enumerated types.
For example, the following code imports the System.Drawing.Drawing2D namespace, which defines the DrawStyle enumeration. It declares the variable dash_style to be of the DashStyle type and sets its value to DashStyle.DashDotDot.
Imports System.Drawing.Drawing2D ... Dim dash_style As DashStyle = DashStyle.DashDotDot ...
The following code also imports the System.Drawing.Drawing2D.DashStyle enumeration. That allows it to set the value of the dash_style variable to DashDotDot without needing to specify the name of the enumeration (DashStyle).
Imports System.Drawing.Drawing2D Imports System.Drawing.Drawing2D.DashStyle ... Dim dash_style As DashStyle = DashDotDot ...