Ken Getz
MCW Technologies, LLC

Updated November 2005

Summary: Get on overview of the new features in Visual Basic 2005 including, My Visual Basic, IntelliSense, Edit and Continue, AutoCorrect, Just My Code, Windows Forms enhancements, and more. (32 printed pages)

Note   This article has been updated for the final release of Visual Basic 2005.

Contents

Introduction
Productivity Enhancements
   The My Namespace
   IntelliSense and Code Snippets
   Edit and Continue
   Debugger DataTips
   AutoCorrect
   Design-Time Expression Evaluation
   Exception Assistant
   Windows Forms Enhancements
   Working with Data
   Just My Code
   ClickOnce Installation
Language Innovations
   Operator Overloading
   Generics
   IsNot Keyword
   Using Keyword
   Unsigned Integer Types
   Partial Classes
   Background Worker Object
Summary

Introduction

Microsoft Visual Studio 2005 has been significantly improved for Visual Basic developers by adding innovative language constructs, new compiler features, dramatically enhanced productivity, and an improved debugging experience. Visual Studio 2005 includes several productivity enhancements including IntelliSense code snippets, Windows Forms designer updates, IntelliSense filtering, debugger data tips, Exception Assistant, and more. In language innovations, Visual Basic 2005 includes generics, unsigned types, operator overloading, and many other additions. This document samples some of the new capabilities available in Visual Basic 2005.

Productivity Enhancements

Visual Studio 2005 and Visual Basic 2005 add many features and tools that make your development experience more productive. The following sections outline just a few.

The My Namespace

Imagine being able to find the functionality you need within the huge set of classes available as part of the .NET Framework immediately. Imagine using a single reference to accomplish goals that would otherwise require many lines of code. Imagine being more productive than you could ever have been programming in previous versions of Visual Basic or Visual Basic 6. These goals, and more, have been met with the addition of the My namespace to Visual Basic 2005.

Like shortcuts on your Windows desktop make it easier for you to find the applications and files you need in Windows, the My namespace classes provide shortcuts to commonly used functionality within the .NET Framework. In addition, the My namespace adds functionality that was previously difficult to find, difficult to use, or was simply not possible without unmanaged API calls.

The My namespace includes the following classes, each of which includes a number of useful members:

  • Application
  • Computer
  • Forms
  • Resources
  • Settings
  • User

For example, to play an audio file in Visual Basic 2005, rather than using DirectX or Win32 API calls, you could write this simple single line of code:

My.Computer.Audio.Play("C:\Beep.wav")

Or, to play a system sound, you might write code like this:

My.Computer.Audio.PlaySystemSound(SystemSounds.Asterisk)

In addition, My namespace supplies functionality that otherwise requires substantial code. For example, the following code demonstrates how you can use simple code to ping a computer:

If My.Computer.Network.IsAvailable Then
    If My.Computer.Network.Ping("http://www.microsoft.com") Then
        MsgBox("Microsoft's site is available.")
    End If
End If

Working with the file system has never been easier. My.Computer.FileSystem provides a flat, stateless, discoverable, and easy-to-use way to perform common file system operations. File system operations such as copying, deleting, moving, and renaming files and folders are at the core of My.Computer.FileSystem. For example, developers frequently require file, folder, and drive properties (such as a file's size, encoding, and so on). Using My.Computer.FileSystem, commonly referenced file, folder, and drive properties can be obtained easily. For example, to display the size of each drive in your system, you might write code like the following:

For Each drv As DriveInfo In My.Computer.FileSystem.Drives
    If drv.IsReady Then
        Debug.WriteLine(String.Format( _
         "{0}:\ {1:N0}", drv.Name, drv.TotalSize))
    End If
Next

The My.User class provides information about the current user, including Name and IsInRole properties. You could use code like the following to display the current user's information and whether the user is an administrator:

MsgBox(My.User.Identity.Name & ":" & _
    My.User.IsInRole("Administrators"))

If you wanted to determine the current user's application data folder, you could use simple code like the following:

MsgBox( _
My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData)

The My namespace also adds functionality that returns many of the RAD features of Visual Basic 6 to the .NET development platform. For example, Visual Basic developers historically accessed forms by name, relying on the runtime engine to maintain a collection of all the available form classes. Using the new My.Forms collection, developers can write code to open and interact with an instance of a form class created as part of a solution, like the following:

My.Forms.HelpForm.Show() 

In addition, the My namespace includes a number of other dynamically created collections, including Forms, WebServices, Resources, and Settings. The My.WebServices collection allows developers to easily call Web Service methods taking advantage of IntelliSense and strong typing, and makes the call simpler as well. For example, imagine a Web Service named Numbers that has already been declared in a project. Calling the NumToStr method of the Web Service couldn't get much easier than this:

MsgBox(My.WebServices.Numbers.NumToStr(123.45))

The My namespace has been devised to make it simpler for Visual Basic developers to accomplish their goals with less work, and with less searching through multiple namespaces. You'll find that many arduous tasks in previous releases are now only a single reference away.

IntelliSense and Code Snippets

Visual Basic 2005 is more aggressive than previous versions when it comes to warning you of coding errors. For example, attempting to use a variable before it has been assigned a value triggers a warning, as shown in Figure 1.

Figure 1. Visual Basic catches common errors at design time.

The new code snippet feature, IntelliSense code snippets, allows you to right-click within the Visual Basic code editor, and select from a hierarchical list of tasks you're most likely to want to accomplish. Selecting a task inserts the prewritten code into your source file for you. Figure 2 shows this feature in action.

Figure 2. Use IntelliSense code snippets within Visual Studio to simplify your coding process.

Once you've inserted the code snippet, you have the option to fix up items such as hard-coded paths and control references, as shown in Figure 3. With your adjustments, the inserted code can work correctly within your environment. The code snippet can include a reference to the appropriate online help topic, and provides tool tips reminding you of changes you need to make. The Insert Snippets option can determine whether you're inside a procedure or not, and can make the appropriate list of snippets available depending on the current context.

Figure 3. Replace values within the code snippet so that the code works correctly for you. Use the Tab key to navigate among the placeholders in the snippet.

Of course, you can create your own code snippets as well. These IntelliSense items are stored as XML files within a folder hierarchy (it's the folder hierarchy that determines the fly-out menus appearing within the code editor), and you have the option of saving your own code snippets, decorating the XML with your own tool tips and help references.

Edit and Continue

Quick development turnaround time has always been the hallmark of developing in Visual Basic, and programmers who miss the edit and continue feature in Visual Basic 6 can rejoice—it's back! In Visual Basic 2005, you can make changes to your code during debugging, back up the code instruction pointer if you want, and re-execute lines of code with the modified content. While in Break mode, you can modify code or fix bugs; almost any code modification will work. (Of course, some modifications force you to switch back to design mode and rebuild the project and there's no way around it.) This change for Visual Studio 2005 has huge numbers of Visual Basic developers cheering!

Debugger DataTips

While in Debug mode using Visual Studio .NET 2003, you could place the cursor over a simple variable, such as a string, to inspect its value. In Visual Studio 2005, this feature has been greatly enhanced; data tips now support complex types, as well. Figure 4 shows a simple example in which the data tip displays information about a complex type, and shows off the ability to drill into the hierarchy for the type. In addition to displaying values, you can also edit those values from within the data tips.

Figure 4. Data tips have been greatly enhanced for Visual Studio 2005. You can investigate complex data structures while debugging, without needing to load a separate window.

AutoCorrect

Visual Basic 2005 adds an AutoCorrect feature, making it simple to determine why invalid code won't compile, and to choose from multiple options in order to fix the errant code. If you make a simple typing error, as shown in Figure 5, clicking the Smart Task produces a list of suggestions from which you can select the correct code.

Figure 5. AutoCorrect can fix typing errors, supplying suggestions based on the text you've entered.

If you attempt to use a class, but neglect to import its namespace or provide the full class name, the AutoCorrect Smart Task offers suggestions, as shown in Figure 6.

Figure 6. If you neglect to import a namespace, you can count on AutoCorrect to supply the full name.

Imagine that you've created a read/write property and then decide to make it read-only. You add the ReadOnly keyword, but of course, now you see a blue "squiggle" indicating that something's wrong with the Set block (see Figure 7).

Figure 7. It's easy to see when code has an error. It's harder to figure out what to do about it. Visual Basic's AutoCorrect makes it easier.

Expanding the Smart Task displayed near the error displays a dialog box, as shown in Figure 8. On this dialog box, you can select either of the possible remedies, and then click the associated link to make the change.

Figure 8. Visual Basic Error Correction dialog box makes it easy to select and apply fixes.

Design-Time Expression Evaluation

Visual Studio 2005 adds back familiar functionality from Visual Basic 6—the ability to evaluate expressions at design time, in the Immediate window. It's useful to be able to call Framework methods and user-defined methods from within the Immediate window in order to test methods, debug code, and more. Figure 9 shows an example of evaluating expressions from within the Immediate window at design time.

Figure 9. Like Visual Basic 6, Visual Basic 2005 allows you to perform calculations in the Immediate window at design time.

You can also call code you've written. For example, Figure 10 shows an example calling code within a form's class. Of course, as you type into the Immediate window in Design mode, you get IntelliSense help just as you do in Break mode.

Figure 10. You can call code you've written yourself while in Design mode, even if the code is inside a form's class.

Exception Assistant

Visual Studio 2005 provides assistance when an unhandled run-time exception occurs. The exception handler bubble provides standard information about the exception, pointing to the exact location within the line of code if it can, and also gives helpful information indicating what to do about the exception, and how to prevent the exception from occurring again. Figure 11 shows the exception assistance bubble in action.

Figure 11. Runtime errors are easy to diagnose using the new Exception Assistant.

Windows Forms Enhancements

Visual Studio 2005 adds many new features in the area of Windows Forms, both at design and run time; there are simply too many to mention them all here. Two of these features make it far easier to lay out forms just the way you want them—snap lines and in-place property editing.

Snap lines make it easy to align controls with other controls as you layout forms. You might want to align a new control with the top of one control and the right side of another. Figure 12 shows such an arrangement. As you move Button3 so that it's near the edges of Button1 and Button2, the Windows Forms designer displays blue snap lines, as shown in Figure 12. You use these snap lines to align Button3 with the right edge of Button1 and the top edge of Button2.

Figure 12. Snap lines can align controls with the edges of other controls.

As you move Button3 along the height of Button2, the text in Button3 aligns with the text in Button2, and red snap lines indicate this, as shown in Figure 13. If you continue to drag Button3 down, the snap lines shift, as shown in Figure 14. Now, it's simple to align Button3 with the bottom of Button2 and the right of Button1.

Figure 13. Snap lines make it easy to align text in controls.

Figure 14. You can use snap lines to align along any edge.

The Windows Forms designer adds a large number of new controls to its stable of existing controls in the 2005 release. You'll find a new ToolStrip control that augments the existing Toolbar control, adding functionality and behavior that makes it easier to create applications emulating the rich Microsoft Office 2003-style user interface. In addition, there are a number of other useful new controls, including the FlowLayoutPanel, TableLayoutPanel, and managed WebBrowser controls. The SplitContainer control is a huge improvement over laying out Panel and Splitter controls as you might have in previous releases. The DataGridView control is a major improvement over the existing DataGrid control, making it far easier to build the exact user experience that you need.

Working with Data

Although the 2005 release of Visual Studio adds too many data-related features to show them all here, two features really stand out in this new version—the DataSources window and drag-and-drop data binding. Visual Studio .NET 2002 and 2003 did a great job making it easy to bind user interface features to data sources, providing the various data adapter components that you could drag and drop onto a particular form. This technique was certainly easier than writing code, but it did affect maintainability; an individual connection object per form made it tricky to modify the location of your data! In Visual Studio 2005, the project-wide DataSources window provides a holistic view of your application's data.

The DataSources window, as shown in Figure 15, allows you to set up project-wide data sources, selecting items to be used from within the application. When you need to work with a specific data item, you can drag a table or group of fields onto a form, and Visual Studio 2005 can create bound controls for you.

Figure 15. The DataSources window allows you to create project-wide data sources that you can drag and drop onto any design surface. You can also refer to these items programmatically.

Binding data to existing controls couldn't be easier, either. Drag a field from the Data Sources window onto an existing control, and Visual Studio 2005 creates the type of control selected in the Data Sources window, and sets the appropriate binding properties so that you don't need to dig into them yourself. If you have existing controls, you can still drag from the Data Sources window. Drag and drop onto an existing control, and the bindings are set up for you, as well. This type of binding (often called "connect the dots" data binding, simply sets the appropriate data binding properties for existing controls. Whether you're creating bound forms by dragging from the DataSources window, or binding existing controls, you no longer need to maintain your data sources in code, nor in individual components on each form. The DataSources window manages all your data sources for you in one convenient location.

Just My Code

When you create a new project in Visual Basic, the project generally includes a lot of code that you didn't write. Visual Basic 2005 adds the option to always skip over any code that you didn't write as you're single-step debugging through your code. The Enable Just My Code Stepping option (see Figure 16) allows you to control this behavior and is enabled by default.

Figure 16. Just My Code stepping allows you to step over code you didn't write, saving you time and effort.

XML code comments

Documenting your code is a crucial part of an application, and Visual Basic 2005 adds support for creating XML-based comments in your code that can easily be extracted, parsed, and turned into documentation. Outside a procedure, enter ''' (a comment that begins with ''') and then press Enter. Visual Studio 2005 creates the structure of the XML-based comments for you, as shown in Figure 17.

Figure 17. Typing ''' inserts XML-based code comments. Fill in the details, and you can easily create code documentation.

If you supply a description for a parameter in the XML comments as the content of the <param> XML element, developers consuming your method will see IntelliSense help, including your description, as they write their code. You can also select a menu item within Visual Studio that creates Web-based documentation from the XML documentation within your project

ClickOnce Installation and Reg-Free COM

Deploying applications built on the .NET Framework has traditionally been a much simpler process than deploying COM-based applications, but the 2005 release of Visual Studio makes deploying Windows applications even easier. With the addition of ClickOnce functionality, you can create and deploy desktop applications using a safe and simple system-controlled installation and update mechanism, allowing for updates, as needed, from a central location.

Starting with the 1.0 release of .NET, most applications written using the .NET Framework (managed applications) were isolated—all their components were installed local to the application, instead of requiring registration and shared components—and allowed for zero-impact deployment. This solved the DLL problems suffered by COM developers, as they attempted to manage the versions of installed components.

In addition, managed Windows applications have had the capability of running from a Web site, ensuring that their content was always current. Using this approach adds many technological limitations because of security implications. In addition, Windows applications generally run slower over the Web, because parts of the application get downloaded as they're needed, and there's no built-in support for offline use.

ClickOnce technology allows for simple deployment, secure and reliable updates, and it's integrated into Visual Studio. You get the best of both worlds; applications run locally but can be deployed and updated over the Web. ClickOnce makes it easy to install your applications and to provide ongoing updates. Rather than forcing you to distribute new versions of your application, you can deploy updates from a centralized server, updating just the portions of the application that have changed.

ClickOnce can deploy your applications to a client machine from a Web location, from a UNC share, or from a file location (such as a CD). When you deploy your applications using a Web link, users click on a link on a Web page, causing the application to download and install on the client computer. This process creates the necessary Start Menu shortcuts and sets up the item in the Add/Remove Programs dialog box. You can also deploy ClickOnce applications so that they run remotely, and don't install anything locally. (You still have the option of creating a standard MSI file, installing applications as you did in previous versions of Visual Studio, of course.)

Although you can accept all the default options for deploying using ClickOnce, it's instructive to see all the available settings. The Properties dialog box for your project includes a Publish option, as shown in Figure 18. You can specify the location from which users download your application, along with several other options.

Figure 18. Select Publish from within the project's Property pages to configure publishing settings.

Clicking the Updates button displays the dialog box shown in Figure 19. Here you can configure whether your application should check for updates automatically, and if so, how often to perform the updates. ClickOnce-installed applications are smart about updates. If you select to have the updates occur in the background as the application is running, the installer actually tears down and rebuilds the application with the new version while the application is running. You can specify the interval at which you'd like the updates to occur, as well.

Figure 19. Select Updates to configure when and how your application downloads its updates.

Once you've created a project you'd like to deploy using ClickOnce, you can right-click on the project in the Solution Explorer window and select Publish from the context menu. You'll see the dialog box shown in Figure 20. Enter a Web site from which users can download your application.

Figure 20. Publish your project from within Visual Studio.

Next, you can select whether the application will be available both online and offline, or only online. Figure 21 shows the page that allows you to select these settings.

Figure 21. As you post the application, you can determine whether it will be available offline.

Once you've approved the settings (see Figure 22), Visual Studio stores the application at the site you've selected, and allows you to test the deployment by browsing to the site, as shown in Figure 23.

Figure 22. Click Finish to complete the publishing of your application.

Figure 23. Browsing to the download site displays this page.

When you click the deployment link on the installation page, ClickOnce first verifies that all the prerequisites have been installed, and then verifies the installation, as shown in Figure 24. Finally, ClickOnce runs the application, and you can run it later, as well, using the shortcut ClickOnce places on your Start menu.

Figure 24. Users must confirm the installation before installing it on their local hard drive.

Updating the application is easy, as well. Once you make changes to the application and modify the version number within the AssemblyInfo.vb file, redeploy the application using the same settings as before. This creates a new folder on the Web server corresponding to your new version number. Then, when users attempt to run the application, they'll see a dialog box like the one shown in Figure 25, and they'll have the opportunity to download and run the updated version of your applications.

Figure 25. When a new version of your application is available, users get notified as they run the older version.

There's more to ClickOnce than you've seen here, but it's certainly easy to get started deploying your applications using this new, exciting technology.

Developers attempting to deploy applications that take advantage of COM components have always faced a daunting challenge because of the very nature of COM components: they must be globally registered on the target machine. This global registration requirement can cause trouble, especially in terms of versioning and application collision—the feature developers love to hate known as "DLL hell."

Deploying .NET components has always been easier: developers can simply isolate a component with the deployed application, or they can install a shared component in the Global Assembly Cache (GAC), where multiple versions of a component can co-exist side by side. Finally, with the addition of Reg-Free COM, you can have the best of both worlds. You can continue to take advantage of existing COM components, but you won't have to worry about registering the components on the target machine.

To test Reg-Free COM, try this experiment. In Visual Basic 6.0, create a simple ActiveX DLL named VBDemo and include the following method within Class1, the class created by the project template:

Public Function GetPath() As String
    GetPath = App.Path
End Function

Build the DLL, saving it in a convenient location. (Remember that when Visual Basic 6.0 builds an ActiveX DLL, it also registers it on the development machine.)

Within Visual Studio 2005, create a new Windows Application project named RegFreeCOMDemo, and set a COM reference to the existing VBDemo DLL. Add a button to the form, and modify the button's Click event handler to call the COM component:

Private Sub Button1_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles Button1.Click
  Dim test As New VBDemo.Class1
  MsgBox(test.GetPath)
End Sub 

Build the Visual Basic 2005 application, and verify that running the application and clicking the button displays the path from which the COM component runs.

Navigate to the bin\release folder for the RegFreeCOMDemo project. Within the folder, you'll find RegFreeCOMDemo.exe, the main project executable. You'll find RegFreeCOMDemo.exe.config, the configuration file. You'll also find Interop.VBDemo.dll, the interop assembly that makes it possible for your application to communicate with the COM component. What you won't find, however, is VBDemo.dll, the COM component itself.

To prove a point, try unregistering VBDemo.dll. (From the Start | Run menu, type regsvr32 /u <path>\VBDemo.dll, specifying the full path for the COM component.) Run the RegFreeCOMDemo.exe application again, and this time, of course, it fails with an exception when you click the button. Because you unregistered the COM component, the code simply can't find it when it needs it.

To demonstrate Reg-Free COM, you'll need to be able to build your project again, so you must now re-register the COM component. (Use regsvr32 from the Start | Run menu again.) Switch back to Visual Studio, and select the Project | View All Files menu item. Within the Solution Explorer window, expand the References node, and select VBDemo in the list of references. In the Properties window, set the Isolated property to True. (See Figure 26.) Rebuild the project, and switch back to the bin\release folder. (You need to run the project outside of Visual Studio to demonstrate Reg-Free COM.)

Figure 26. When a new version of your application is available, users get notified as they run the older version.

Now, when you investigate the files in the bin\release folder, you should find a copy of VBDemo.dll. It's this copy that your application will use, rather than the globally registered copy. At this point, remove the net—that is, unregister VBDemo again. Run the application, and amazingly, it continues to work. This time, the application displays the current path, because the component is running from within the current path. Because Visual Studio has copied the DLL locally, and because of Reg-Free COM support, your application can use a local copy instead of the globally registered copy.

Obviously, getting Reg-Free COM to work requires more effort than simply copying the COM component locally. If you examine the files within the output folder, you'll also find RegFreeCOMDemo.exe.manifest. If you open this file with a text editor, you'll see that the manifest file contains information about the COM component, and it's this file that makes Reg-Free COM work. If you copy RegFreeCOMDemo.exe along the manifest file and the COM component to a new computer running Windows XP, the application would continue to run. Combined with ClickOnce deployment, it's easy to see how Reg-Free COM makes developers lives simpler—no more hassles with registering COM components and no more DLL hell.

Reg-Free COM does have some limitations, as you might imagine. It requires Windows XP or later in order to run—if you attempt to deploy your application to an earlier version of Windows, you'll see an error message indicating that you need a later version of Windows. Reg-Free COM is perfect for deploying ActiveX controls, ActiveX DLLs, and other business objects, but it won't really work for all components. It only works for in-process components, so ActiveX EXEs are out. It won't work for COM components that are part of the operating system. Reg-Free COM also won't work for COM components that require a larger application—attempting to use Reg-Free COM with the Microsoft Word or Microsoft Excel type libraries, for example, wont' work, because these type libraries require a full copy of Word or Excel to be installed on the target machine. For a large percentage of COM components that you'll want to deploy with your applications, however, Reg-Free COM can make your life a lot easier. For more information on Reg-Free COM, read Simplify App Deployment with ClickOnce and Registration-Free COM.

Language Innovations

Continuing a tradition of balancing power and flexibility with ease of use, Visual Basic 2005 adds a number of new features that keep Visual Basic in sync with the .NET Framework and make it the premier language for business application development. The following sections outline some of the new language features in Visual Basic 2005.

Operator Overloading

The .NET Framework has historically supported overloaded operators, and Visual Basic adds support for this feature in the 2005 release. This feature allows developers to consume operators whose functionality has been overloaded by a particular class (a feature that wasn't available in previous releases) and it also allows developers to overload the functionality for the standard language operators, such as +, -, *, /, and so on.

You have most likely taken overloaded operator behavior for granted in classes where it's already supported. Although it may not be common practice to write code like this, the code works because of the overloaded + operator:

Dim inputString as String = "Hello, "
Dim outputString As String = inputString + " World!"

The + operator is generally only defined for numeric values, but the String class overloaded the behavior of the operator so that it concatenates its two operands.

The operator overloading feature in Visual Basic 2005 consists of two distinct parts: consumption and declaration. Consumption is easy to demonstrate; take the Point structure, for example. You often need to take an existing Point instance and add a Size structure to it, effectively offsetting the Point by the values stored in the Size structure. The Point class includes code to handle addition and subtraction operations, using the standard + and – operators. That is, the following code does just what you might expect:

Dim p1 As New Point(100, 100)
Dim s1 As New Size(20, 30)

Dim p2 As Point = p1 + s1
Dim p3 As Point = p1 – s1

After this code executes, p2 contains {120, 130} and p3 contains {80, 70}, as you might expect. At compile time, the compiler locates the correct special function, defined to handle addition or subtraction of Point and Size structures, and turns the addition and subtraction operators into function calls to the special functions. The following code, required in previous versions of Visual Basic, demonstrates how you might add Point and Size values without support for operator overloading:

Dim p2 As point = Point.op_Addition(p1, s1)

The developers who created the code for the Point structure provided the op_Addition function (and the corresponding op_Subtraction, op_Equality, and so on). If these functions didn't exist, the code wouldn't have compiled because the compiler must convert from the overloaded operators into the appropriate function call at compile time. An expression like "p1 + s1" is, in reality, simply a function call to the appropriate addition function, with two arguments, like this:

Point.op_Addition(p1, s1)

Because the addition function is simply a procedure, the compiler can determine which overloaded version to use, based on the parameters. Because of the new operator overloading functionality built into Visual Basic 2005, you can perform operations such as those shown here using standard mathematical operators on the Point and Size structures. (In previous versions of Visual Basic, you were required to call the op_Addition method explicitly, for example, to add a Point and a Size structure.)

Although it's not likely a feature you'll need often, Visual Basic 2005 also adds support for creating your own overloaded operators. The Visual Basic compiler allows you to overload many operators, as shown in the following table:

+ + (unary)
- - (unary)
* \
/ ^
& Like
Mode And
Or Xor
Not <<
>> = (comparison)
<> <
<= >
>= CType
IsTrue IsFalse

Generics

Before looking at the concept of generics and how they can help you write better, more efficient, and maintainable Visual Basic code, examine a common scenario. Let's say that you've created a class as part of an application, and you'd like to create a collection containing instances of that class. For this example, you have created a simple class, named Customer, containing the following code:

Class Customer
    Public Name As String
    Public Age As Integer

    Public Sub New(ByVal Name As String, ByVal Age As String)
        Me.Name = Name
        Me.Age = Age
    End Sub
End Class

If you want to create a data structure that contains a collection of Customer objects, you could use the System.Collections.ArrayList class and could write code like this:

Dim customerList As New System.Collections.ArrayList
customerList.Add(New Customer("Tom", 48))
customerList.Add(New Customer("Peter", 45))
customerList.Add(New Customer("Jerry", 73))
customerList.Add("Hello, this won't work!")

For Each cust As Customer In customerList
    Console.WriteLine(cust.Name)
Next

Note the inconsistency in the data. Although the ArrayList class allows you to insert Customer objects, it also is just as obliging when it comes to String, Integer, or any other object type. The simplicity of the ArrayList class leads to its downfall—there's no way to easily restrict the type of data you add to it. Exposing a public ArrayList as a property of a class is a recipe for disaster, if you care about data integrity.

Creating your own collection class that derives from the System.Collections.CollectionBase class provides a type-safe alternative. For example, the following class allows only Customer objects to be added to its collection:

Class CustomerList
    Inherits CollectionBase

    Public Sub Add(ByVal cust As Customer)
        Me.List.Add(cust)
    End Sub
End Class

Given the CustomerList class, it would be impossible to add any object to your collection that wasn't a Customer object. This solution is fine, as long as you only work with Customer objects. What happens when you also need a strongly typed collection class for working with Invoices? Or later, when you need a collection for Products, Orders, and so on? Creating and maintaining individual collection classes for each type could become a maintenance nightmare. Therein lies the motivation for the new language feature: generics.

Generics allow classes, structs, interfaces, and methods to be parameterized by the types of data they store and manipulate. Generics are useful because many common classes and structures can be parameterized in this way. These are called generic declarations. The .NET Framework provides a group of generic collection classes as part of its System.Collections.Generic namespace.

For example, the System.Collections.Generic namespace provides a generic List class. To consume the List class, you must supply the type for the items within the collection at the time you declare the instance of the list, like this (assuming that you've added an Imports statement for the System.Collections.Generic namespace to your code file):

Dim customerList As New List(Of Customer)

As you can probably guess, the "Of" keyword allows you to specify the type associated with elements of the generic collection. To use the generic List class, you could write code like the following:

Dim customerList As New List(Of Customer)
customerList.Add(New Customer("Tom", 48))
customerList.Add(New Customer("Ken", 47))
customerList.Add(New Customer("Peter", 45))
customerList.Add(New Customer("Jerry", 73))

For Each cust As Customer In customerList
    Console.WriteLine(cust.Name)
Next

Of course, once you've created an instance of the List class with a Customer type as its type argument (or any other type, for that matter), you are limited to storing only Customer objects (or objects of a class derived from Customer). Generics provide strong typing, meaning you can no longer improperly store any other type into the list. Take, for example, this code:

Dim customerList As New List(Of Customer)
customerList.Add(New Customer("Tom", 48))
customerList.Add("Hello there!")
Dim c As Customer = customerList(0)

Notice two important things:

  • Unless you remove the third line, the code won't compile. The compiler checks to verify that you're using the object created by the generic class definition correctly.
  • In the final line, there's no need to cast the value returned from the List object. Each element contained within the List instance is always of the type specified when you declare the instance of the List class.

Besides the List class, the System.Collections.Generic namespace also provides generic versions of the Dictionary, SortedDictionary, LinkedList, Queue, and Stack classes. Because the .NET Framework includes so many generic collection classes, it's unlikely that you'll need to create your own generic class. If you find a need to create your own, however, Visual Basic 2005 makes it possible.

For example, if you needed to create a class that contained a one-dimensional array of a single data type (often called a vector), you might create a class like the following:

Public Class TypedVector(Of T)
    ' Create a one-dimensional array of 
    ' the specified type.
    Private arrayValue() As T

    Public Sub New(ByVal Size As Integer)
        ReDim arrayValue(Size - 1)
    End Sub

    Default Public Property Item(ByVal Index As Integer) As T
        Get
            Return arrayValue(Index)
        End Get
        Set(ByVal Value As T)
            arrayValue(Index) = Value
        End Set
    End Property
End Class

When you use the generic class declaration TypedVector, as in the example that follows, you can specify the actual type to be used by the generic class. In this case, the code instructs the TypedVector class to use the Integer type by specifying it as a type argument with the "(Of Integer)" syntax after the class name. This example creates an array containing five integers:

Dim myVector As New TypedVector(Of Integer)(4)
myVector(0) = 73
myVector(1) = 27
' Fill the rest of the items...

To create a TypedVector instance that could contain only instances of some specific business type, perhaps Customer objects, you could use code like the following:

Dim myVector As New TypedVector(Of Customer)(11)
myVector(0) = someCustomerObject

It's clear that you won't need generics for every application you write. When you do need to create a strongly typed collection, there's no better solution than to take advantage of either the built-in classes from the System.Collections.Generic namespace or to create your own generic collection class.

IsNot Keyword

Although it hasn't been a terrible burden in the past, determining whether an object reference is not the same as another object reference has historically involved a somewhat clumsy construct:

If Not (obj Is Nothing) Then

Visual Basic 2005 adds the IsNot keyword, making it possible to rewrite the previous example:

If obj IsNot Nothing Then

Sometimes, it's the little things that make a big difference.

Using Keyword

Many classes in the .NET Framework provide a Dispose method as a standard mechanism for releasing resources used by the object. In general, it's a good rule of thumb to call the Dispose method of an object you're using when you're done with the object. When you're working with managed wrappers around unmanaged or limited resources, as is the case when you work with a database connection or a Windows font or brush, you should always explicitly call the Dispose method if the object provides it, in order to release the unmanaged resource. Imagine a form that draws text in a specific font and brush in its Paint event handler. In previous versions of Visual Basic, you were required to write code something like the following:

Private Sub Form1_Paint( _
 ByVal sender As Object, ByVal e As PaintEventArgs) _
 Handles MyBase.Paint

    Dim myFont As Font
    Dim myBrush As Brush
    Try
        myFont = New Font("Verdana", 12)
        myBrush = New SolidBrush(Color.FromArgb(123, 0, 123))
        e.Graphics.DrawString( _
         "Hello, World!", myFont, myBrush, 0, 0)

    Finally
        If myFont IsNot Nothing Then
            myFont.Dispose()
        End If

        If myBrush IsNot Nothing Then
            myBrush.Dispose()
        End If
    End Try
End Sub

Visual Basic 2005 adds the Using keyword, which creates a block of code that disposes of an object for you at the end of the block, no matter how the block is exited. The previous code example can be rewritten more efficiently, as in the following example:

Private Sub Form1_Paint( _
 ByVal sender As Object, ByVal e As PaintEventArgs) _
 Handles MyBase.Paint
    ' Create a new font.
    Using myFont As New Font("Verdana", 12)
        ' Create a new solid brush.
        Using myBrush As New SolidBrush( _
         Color.FromArgb(123, 0, 123))
            e.Graphics.DrawString( _
             "Hello, World!", myFont, myBrush, 0, 0)
        End Using
    End Using
End Sub

Unsigned Integer Types

Historically, Visual Basic has supported unsigned byte and signed integer types, but it hasn't supported signed bytes or unsigned integers. In Visual Basic .NET 2002 and 2003, developers could create and use the .NET Framework's unsigned types, but they couldn't perform mathematical operations on these values. Visual Basic 2005 adds full support for these types, as well as the necessary corresponding conversion methods. The following table lists the four new intrinsic types (SByte has no type character because Byte has no type character):

VB Keyword Conversion Operator Type Character Range CLR Name
SByte (1 byte) CSByte(o) (None) -128 through 127 System.SByte
UShort (2 bytes) CUShort(o) US 0 through 65,535 System.UInt16
UInteger (4 bytes) CUInt(o) UI 0 through 4,294,967,295 System.UInt32
ULong (8 bytes) CULng(o) UL 0 through 18,446,744,073,709,551,615 (1.8...E+19) System.UInt64

Partial Classes

Partial classes allow a single class to be split into multiple files. Although this may seem like a feature that won't affect your day-to-day development, it's a feature that will play a part in just about every application you write. The most useful aspect of this feature is for code generators like Visual Studio that can generate code into a different file than user-written code, but still provide functionality within the same class as the user's code. In this manner, the visual designer can more easily parse and regenerate its code without affecting the code the user has written.

The primary class is created just like a normal class, but the additional portions that the class contains are declared using the Partial keyword. For example, you might see code like the following:

Public Class Form1
  Inherits Windows.Forms.Form
  ' Your Code
End Class

Partial Public Class Form1
  ' Designer code
  Sub InitializeComponent()
    ' Information about your controls goes here...
  End Sub
End Class

A single class can be broken up into multiple partial classes and all partial classes of the same name, within the same namespace, are compiled into a single entity at compile time. This feature figures prominently in the way Visual Studio manages your code, making it easy for tools provided by the environment to update their code but leave yours intact. This is a feature you'll want to consider when working on projects with multiple developers. Having classes split across multiple files makes it far easier to manage source control with concurrent modification of the same class.

Background Worker Object

Handling asynchronous processing has always been a difficult area for many Visual Basic developers, and ensuring that the callback procedure ran on the correct thread caused many headaches in previous versions. Visual Basic 2005 developers can take advantage of the BackgroundWorker component to handle these tasks automatically. By dragging this component onto any design surface, developers can easily run slow-running processes as background tasks.

By calling the RunWorkerAsync method of the BackgroundWorker component, developers can execute code in the DoWork event handler of the component. This code runs in a separate thread from the main user-interface thread, allowing the user interface to continue while the slower running process executes without blocking the main thread. When the background task is complete, the BackgroundWorker component raises its RunWorkerComplete event, allowing the caller to react to the fact that the task is completed. The RunWorkerComplete event handler also runs in the main thread, making it possible to update controls on the form containing the component.

If you've thought asynchronous processing was too difficult, or if you've fought with and never mastered the various intricacies of multi-threaded user interfaces, the BackgroundWorker component can make your life easier. You won't need to worry about the thread safety of your forms, and you'll be able to simply add background processing to applications using this powerful new component.

Summary

As you can see from the few additions listed here, Visual Basic 2005 continues to build on the success of Visual Basic .NET 2003, with its goal of providing the best environment and language for creating applications quickly. With the new language features, IDE features, and productivity tools, Visual Basic 2005 allows you to work more productively, using all the language features provided by the .NET Framework.