Hidden Gems in Visual Basic 2008 (Amanda Silver)


Yesterday I promised to post about the hidden gems in Visual Basic and Visual Studio 2008 that you haven’t read about in blog posts or seen at conferences. I forgot that I mentioned a few of my favorite features in the Beta1 announcement where I showed off the improvements in the Intellisense experience – statement completion for keywords, local variables, and expressions. In that post, I also cover a new language feature called Relaxed Delegates which allows you to provide alternate signatures for events. Both of those are pretty great features – but I promised to tell you about some new stuff.

I polled the team and we came up with the following top ten that weren’t mentioned in my previous post. There’s so much I could talk about – but you’re going to have to check back. But first, I have to start with a keynote feature…

0) Multi-targetting

In short, multi-targetting allows you to use Visual Studio 2008 (and VB 9!) to target the .NET 2.0 frameworks. All of the following features I’ll show you can be leveraged even if you’re targeting .NET 2.0! (With the exception of items #5 & #7 as they depend on the LINQ to Objects and LINQ to XML APIs which reside in .NET 3.5) To do this, when you start up Visual Studio and create a new project, just make sure that the target framework is set to .NET Framework 2.0.


Note that projects you’re upgrading, will automatically target .NET Framework 2.0 until you add references to .NET 3.0 or 3.5 assemblies.

1) Type Inference

In Visual Basic 9, in the following bit of code and NOTHING is late-bound – everything is bound at compile-time which means you get Intellisense and type checking.

        Dim dialog = New OpenFileDialog()
        Dim result = dialog.ShowDialog()
        Dim printStr = "C:"
        If result = Windows.Forms.DialogResult.OK Then
            printStr = dialog.FileName
        End If

This makes prototyping very quick, easy, and type-safe! This feature and the mechanisms that control it are comprehensively covered in this article by a member of our QA team, Bill Horst.

2) If Operator

Ever notice that the IIF function returns something of type Object? This means that you don’t get Intellisense or type-checking by default on that result. For those of you that insist on type-safe, early-bound code, you have to cast the result. The code then looks something like this:

        Dim intC As Integer = CInt(IIf(intA = intB, intA, intB - 1))

With the If operator, you can now write that line as:

        Dim intD As Integer = If(intA = intB, intA, intB)

And with type inference it gets even easier on the eyes:


I’m a fan of any feature that improves readability.

3) Object Initializers

Generally, in the .NET frameworks, we try to design APIs that use the create-set-call pattern as our usability studies have indicated they are the easiest to use by the average programmer. Nevertheless, objects that don’t have a parameterless constructor exist in the .NET framework. When that happens, it’s really nice to be able to leverage Object Initializers which are kind of like a Dim and a With statement combined into an expression. That makes parameterized constructors somewhat easier to tolerate:

        Dim strm As New StreamWriter( _
                      New FileStream("C:out.txt", FileMode.OpenOrCreate) _
                        With {.Position = 10})

It also makes creating arrays of objects much easier.

        Dim Capitals() As City = {New City With {.Name = "Antanarivo", .Country = "Madagascar"}, _
          New City With {.Name = "Belmopan", .Country = "Belize"}, _
          New City With {.Name = "Monaco", .Country = "Monaco"}, _
          New City With {.Country = "Palau", .Name = "Koror"}}

4) Nullable

Nullable is the feature you’ll notice but rarely have to think about. It’s basically the .NET representation for a Nullable value type (Integer, Date, etc.) Using the designer for LINQ to SQL, the Object-Relational Mapping layer introduced in Visual Studio 2008, nullable columns in your database are mapped to this type. The result is that you can write the following expression in VB and the right thing happens – null valued rows propagate null. In the example below, the Independence property on the Country type is a nullable date, denoted as Date?

        Dim virginIslands As New Country With {.Independence = Nothing}
        Dim palau As New Country With {.Independence = #10/1/1994#}
        Dim vILength = #8/24/2005# - virginIslands.Independence ' Nothing
        Dim pLength = #8/24/2005# - palau.Independence ' 3980.00:00:00

5) LINQ to DataSet

I love this feature because it means never having to say you’re sorry… No, really, it means that you don’t need to migrate to a new data access technology to reap the benefits of LINQ. I fill my DataSet just as before, and then I can query against the DataSet:

        Dim query = From emp In Me.NORTHWNDDataSet.Employees _
                    Where emp.Country = "USA" _
                    Order By emp.HireDate _
                    Select emp
        Me.EmployeesBindingSource.DataSource = query

6) Syntax Tooltips

How cool is this?


How about this?


What do you think of this?


7) XML Namespace support in Intellisense

We’ve blogged about XML Intellisense before. But there’s a tidbit we’ve overlooked.

When namespaces are used in the XML document you’re reading from, the Intellisense engine matches the namespace prefix and the local name. This little productivity boost can yield a significant savings in keystrokes. Instead of typing the prefix then the colon and then the local name, you just type a little bit of the local name and hit enter. Here is a small example of how it works, starting with an input document and the applicable intellisense:


If we just type the letter “t” the “tomato” entry will be selected:


If we type the letter “e” the “exa:eggplant” will be selected and the completion list will also contain the prefix “exa” and the “elephant” entry:


The next character that will be typed will determine which single entry will get selected. Now, how easy was that?

8) GoTo Type Definition

Often, when you define a variable, you want to view the type definition in code or in the Object Browser. There’s a new option in the context menu which allows you to go directly to the type definition instead of just the variable declaration. This is great when combined with type inference as it allows you confirm that the type of the variable is actually what you believe it to be.


9) Type inference for loop variables

Check out the following code:


And this code:


Without having to specify the type of the control variable, it’s inferred from right-hand-side expression or the collection we’re iterating over.

10) Performance improvements and… Non-blocking operations!

The background compiler is an awesome feature that gives you immediate feedback on the correctness of the code you write. We’ve made some tremendous strides in the performance of the background compiler in this release. We believe that the background compiler is 3 times faster uses 3 times less memory. Anyone who has migrated their project to 2008 should notice an improvement after a couple minutes of use.

While we’ve made huge improvements on the throughput, certain operations like changing the declaration of a base class that’s used many times in a large project is computationally expensive. If you attempted to invoke a feature that relied on compiled information before the background compiler has a chance to do its magic, like Intellisense or the Drop Downs, previous versions of Visual Studio would grind to a halt until the compilation was complete. Those operations are no-longer blocking. So, while you might occasionally get the drop downs to look like this:


The IDE will still be responsive.

Now do you have to download it? Remember, you can always grab the Express Edition!


Leave a comment

Feedback usabilla icon