When you use Visual Studio 2008 for the first time, you will notice some big changes in IntelliSense. Although IntelliSense is largely a function of the Visual Studio IDE, I have included it in this article because I suspect that VB developers depend more heavily on IntelliSense than others, and because the changes are so useful. As you probably suspected, this feature is available even if you don't upgrade to the .NET Framework 3.5.
|Figure 3. Visual Studio 2005 Intellisense: Visual Studio 2005 provided a smaller set of 'sensible' items than Visual Studio 2008, but you had to type "Me." Before you could see a button named "btnIntelliSense" in the list.|
To illustrate the changes, suppose you use the common convention of assigning the prefix btn
to your button names, for example btnClose
. Previous versions of Visual Studio required you to type "Me.btn" to retrieve an IntelliSense list of the buttons on a form whose names begin with "btn" (see Figure 3
In contrast, VS2008 attempts to provide IntelliSense after nearly every keystroke, so by simply typing "btn" (not "Me.btn"), you get an IntelliSense list of in-scope members and language keywords starting with "btn" (see Figure 4
|Figure 4. Visual Studio 2008 Intellisense: In Visual Studio 2008 you can get to the button name in the IntelliSense list without typing the "Me." qualifier.||
|Figure 5. Enhanced IntelliSense: Visual Studio 2008 makes IntelliSense a more comprehensive programming aid by including more language terms, such as keywords.||
Even better, the improved IntelliSense list includes even language keywords such as Dim
(see Figure 5
). Best of all, the increased IntelliSense involvement causes no noticeable delay.
Snippets That Work
In case you haven't used this feature before, here's a simple demo. Open a class or module and type the word "property," then press the Tab key. Visual Studio replaces the word "property" with a property snippet—a private local variable declaration followed by a public property, called NewProperty
Private newPropertyValue As String
Public Property NewProperty() As String
Set(ByVal value As String)
newPropertyValue = value
|Figure 6. Unwanted Highlighting: In Visual Studio 2005 it was difficult to get rid of the green snippet highlighting.|
To customize the snippet, you can simply type over the snippet's highlighted areas to provide your own names or types, and press Tab to move to the next highlighted area. Figure 6
shows a new property snippet modified to support an age variable.
The improvement lies in the highlighting. In previous versions the highlighted areas wouldn't go away even after you replaced the default values until you had saved, closed, and then reopened the file. Now, though, if you simply move your cursor outside the property text area and press Enter; the highlighting disappears. Very nice indeed! True, the new snippet functionality is an IDE enhancement rather than a part of VB9, but I liked it so much I thought it would be good to include in this article.
Another feature I really like is "friend assemblies." The Visual Basic Friend
keyword extends the scope of a class, module, or method to the entire assembly where the object is defined. The friend assemblies
feature lets you scope an entire assembly to the same level. In other words, by using the Friend
keyword, a class may now expose all its declarations to another assembly in the same way that it could formerly expose its declarations to other code files in the same project.
On the surface, this feature doesn't seem very useful. However, consider a tool that includes a heavily used run-time component and several debugging and management tools. In such a situation, one might be compelled to keep the size of the run-time assembly as small as possible, pushing functionality not required by the run-time component into another assembly. By doing that, debugging or management components would not be privy to the Friend
status they would enjoy if they were included in the run-time assembly. The now-external components would have to access the run-time components via public interfaces on the run-time assembly. That means you'd have to expose at least some portions of your application's internal state using a public interface—and that could be a security problem.
Using VB9's friend assemblies, you could declare inside the run-time component that the Friend
scope should include the debugging assembly. That would give the debugging assembly code access to methods and values inside the run-time assembly without unnecessarily exposing otherwise private methods and properties through public interfaces.
Another possible use is to give Friend
scope to unit test assemblies. Writing unit tests can sometimes be difficult if the functionality you're trying to test isn't visible outside the assembly. In this case, you would extend Friend
scope to the unit test assembly.
To demonstrate friend assemblies, you'll find two projects in the sample code named VB9_Demo and VB9_Tools. Inside VB9_Demo's frmDemo class, the btnFriendAssemblies_Click
event calls a method declared in the MyTools class in the VB9_Tools project. It can do this because the MyTools class is declared as Friend
. In previous versions, that would have restricted its visibility to only other classes and modules inside the VB9_Tools project. To extend the "friend" scope of the MyTools class to include the VB9_Demo assembly, you must remember to do two things:
- Import the System.Runtime.CompilerServices namespace. That's required because that's where the InternalsVisibleTo attribute is declared.
- Add the InternalsVisibleTo attribute to the MyTools class declaration as shown below:
Friend Class MyTools
Friend Shared Function GetTime() As String
Return "The current time is " & Now.ToLongTimeString()