Visual Studio 2017 just shipped, and with it shipped a new version of Visual Basic. With the new language strategy of the .NET Languages, the focus is again on Visual Basic’s original virtue: Provide editor, debugging and refactoring tools as well as language feature to ease complex tasks and boost every VB’s developer productivity without distracting them from their domain specific excellence. After all, it always was first Visual Basic which put the ‘Visual’ into Visual Studio, and let developers get the work done efficiently, yet without compromises in quality! 😎
Speed up Solution Loading times with Enable Lightweight Solution Load
One of the most important changes in Visual Studio 2017 is improved performance. In many areas, Visual Studio 2017 got considerable faster than Visual Studio 2015. In one discipline, however, you can speed up waiting time for your really big Visual Basic solutions a lot: You just need to Enable Lightweight Solution Load.
To this end,
- Open your large solution as you always do.
- From the Context menu of the solution in the solution explorer, click Enable Lightweight Solution Load.
- Restart Visual Studio, and reload your Solution to observe the differences in load time.
After a few seconds of preparation time, the solution loads and is there almost instantly. Notice though, when you do this for the first time, all the branches of the solution explorer tree view are closed. Visual Studio remembers also for solutions with lightweight loading, which branches were open when you closed the solution, and reopens them on next load. Keep in mind though, that projects get loaded, when their correlated branch is open – so the more branches you had open when you quit Visual Studio, the longer it takes to reload your solution on next start.
New IDE Features
As a Visual Basic developer, you attach importance to a productive IDE, which helps you focus on and speed up your daily VB development tasks. Visual Studio 2017 introduces a great deal of new features around IntelliSense, refactoring and navigation to that end.
Structure Guide Lines
One of the most obvious new aids you’ll notice after you started Visual Studio for the first time, are Structure Guide Lines. When you’re editing extensive methods, which are more than a screen page long, Structure Guide Lines help you to keep track of the structure indent level you’re currently seeing and editing. Just hover with the mouse over a guideline and let the editor give you an overview over the current structure levels.
Since Visual Basic 5.0, IntelliSense has always been a great source for finding and exploring types or all a type’s members. Visual Studio 2017 lets types become even more quickly discoverable by introducing IntelliSense filtering and highlighting. Imagine, for example, you wanted to find all the Async methods which a type provides, since you’re refactoring an app to become more responsive:
Press Space to open IntelliSense. At the bottom of the list you’ll find filter icons, each of which allowing you to limit the IntelliSense list to properties, methods, local variables, and much more. Click on an icon to add the filter category to the result list. Click another time to hide the category from the list. Continue typing to filter the list to the characters you already typed in – those characters get highlighted in the result list. You do not need the mouse to filter the IntelliSense list: When you hover over the filter icons, Visual Studio shows you the keyboard short cuts for the different categories for filtering the list without the mouse.
Apart from the Visual Basic IntelliSense standard settings, Visual Studio allows you to configure IntelliSense for usage in the Visual Basic code editor. To this end, from the Tools pulldown menu, pick Options, and in the Search box type in ‘IntelliSense’. Click on the entry IntelliSense under Text Editor/Basic.
The Visual Studio IDE helps you constantly improve your Visual Basic code. If your open a Visual Basic code file, look out for four gray dots in your code:
Move the cursor to the line. The Lightbulb shows up. Now either press Ctrl+. or Alt + Enter on the keyboard – alternatively hover the mouse over the Lightbulb, and open Quick Actions by clicking. Pick one of the offered code suggestions (e.g. Fix Name Violation: MoveButton_Click) from the menu, or Suppress the suggestion. If you want to suppress a code suggestion, you can do this for just this spot by letting Quick Actions surround the code line with a correlating #Disable Warning directive. If you don’t like to annotate your code with those directives, because you think too many of them are making the code hard to read, Quick Actions can also create or maintain a suppression file for the current project for you, in which all suppression spots are collected.
Configure Code Styles and Code Suggestions
If you want to configure coding style rules (and the resulting code suggestions) on a more global scale, Visual Studio 2017 offers you to configure rules to this end in two ways: Use the configuration dialog for Code Styles, which you can display by picking Options from the Tools pulldown menu. In the tree view, find the category Text Editor, Basic, Code Style.
Use .editorconfig files
When you work on bigger solutions in a team, you need to configure your code style in a different way, because changes to the configuration need to affect the Editor’s behavior for that project of every team member. To this end, you can include .editorconfig files which hold the code style settings either for the whole solution (you would need to put this file in a Solution folder) or a single project.
Kasey Uhlenhuth from the Visual Studio Team explains .editorconfig files here in more detail.
New Debugging Aids
Visual Studio 2017 got a couple of new debugging aids for Visual Basic Developers. First: The exception helper dialog has been modernized and is now much easier to handle. And there is more!
New Exception Helper
The new Exception Helper is a great improvement, when you examine Exceptions during a Visual Basic debug session. One of the most helpful new features of this new Exception Helper is how it can assist you to find out, which part of an expression actually caused a NullReferenceException. The Exception Helper shows you the exact spot within the expression where the NullReferenceException occurred.
There are some limitations though: This does not work when you’re debugging JIT-optimized code (which results for example when you compile with the default Release setting), when expressions involve boxing/unboxing (ValueType via DirectCast or CType from Object), when Nullable types are involved or when you involve array references.
In addition, the exception helper is no longer a modal dialog like the Exception Assistant has been, so it is much easier to handle when you debug your application. And on top, if you open the exception details, you can evaluate the exception right in that dialog, and even add the exception expression to the current Watch tool window.
Run execution to here
Assume, you need to debug a very extensive method step-by-step. Of course, the first thing you do is setting breakpoints at those spots where you suspect bugs or faulty code to be. And now the challenge begins: While you are debugging the code, you need to skip over code parts, which are really time-consuming to debug step-by-step – like loops. What you had to do until now is setting temporary breakpoints at those spots, at which you wanted to continue debugging, then continue program execution (F5), and when the debugger hit such a temporary breakpoint, you would immediately delete it and continue debugging step-by-step. Or, you needed to set the cursor in that line, and from the menu or with a shortcut use the Debug Function Run to Cursor. In Visual Basic 2017 things got much easier, and you do not need to do that anymore – you can just use the Run to Click experience with the function Run execution to here: When you are debugging, in front of each line, you’ll find a little arrow. Click on it, and the debugger runs the app until it reaches that line – where it automatically breaks. If that line isn’t reached, the program runs to the end.
New Refactorings for VB
Visual Basic 2017 got some cool new Refactoring tools. Visual Basic 2010 already introduced the refactoring tool category Generate from Usage which helped you to use Classes, Interfaces, Properties and other Elements first, and let the IDE then generate the Code for those items you already used.
As an example, insert a line of code in a method using a class, which does not yet exist (make sure to start the class name with a capital letter, because otherwise the IDE won’t show the code generation options):
With Quick Actions, Visual Studio 2015 gave you already a bunch of options to create a new type.
Visual Basic 2017 lets you in addition…
Move Type to matching File
… move a type, which is defined along with other Classes or Structures in the same code file, automatically to its own code file with the corresponding filename.
Sync type and Filename
If you already have a separate code file for a Class, an Enum or a Module, but the filename ended up to be different from the element’s name in the code, with Visual Studio 2017 it’s just one click to sync both names:
Find all references
Previous versions of Visual Studio already introduced Find all References, so you could get a quick glance of where in your solution you used a certain class, method, property or other type items. To find a reference of an item, just click on that element in the code file, open the context menu and klick Find all References. In contrast to previous versions, the result list in Visual Studio 2017 is now much more useful and clearly arranged. Try it out:
New VB Language Features
In terms of language, Visual Basic 2017 also got new features – Tuples being the most important one. But there is also one new ability of the language which reflects the new language strategy for VB: VB does not need to get every single new feature C# gets. Rather, refining VB should address the VB target’s audience which is usually different from the C# audience and therefore demands different kind of language features and tooling. That said, it is very important, that Visual Basic will be able to use every aspect of a library which has been created in C# with features Visual Basic does neither have nor need itself. Ref Returns (see below) is a perfect sample for such a scenario.
When you write methods in VB, which return values, you often find yourself in a situation, where you need to return more than one result value to the caller. If this happens, you got some options:
- Create a new Class or a new Structure to integrate the results, and return that Class or Structure.
- Work with ByRef Parameters, so you can return more than one variable.
- Work with Tuples!
The framework already has a couple of methods, which work with the ByRef alternative. Take a look at how the TryParse works, which you find on most of the primitive data types:
This is kind of cumbersome, don’t you think? If TryParse could return a Tuple, things would be much easier. Like this:
That is easy to use! Let’s see how Tuples work in detail. Tuple are not new to Visual Basic. They just weren’t very comfortable to use, yet. The new Tuple language feature in Visual Basic 2017 does rely on a different kind of type than Tuple(Of T). For those frameworks, which do not already contain the new type ValueTuple(Of T), you need to install a NuGet package to your project, before you can use this new language feature in your code. This is just for the time being. Later Framework versions will have them included automatically. To add the NuGet package, in the Solution Explorer open the context menu of your VB project, and click Manage NuGets. With the NuGet Manager, find and install the ValueTuple NuGet package into your project:
Before Visual Basic 2017, the only way you could use Tuples looked something like that:
As you can see, there wasn’t a nice way to infer the definition, and Tuple elements could also only be addressed by Item1, Item2, etc.
This is how you basically use Tuples now, and go back and forth between the old and the new Tuples versions in Visual Basic 2017:
Really cool is that you can name the Tuple elements for the current scope.
Tuples can also be used in expressions. For example, when you want to directly return them from a Function block…
…or when you use them with Select in an LINQ-Expression:
Binary Literals and Digit Separators
This is only a minor addition to Visual Basic, but it is helpful anyway, and it makes your code easier to read: You can use Binary Literals in VB from now on. You already had Hexadecimal Literals before – in the same way, Visual Studio now supports Binary Literals. On top, VB also got digit separators, so numbers with a lot of digits can be read more easily:
We just learned, Tuples are great if you want to return more than one variable back to the caller. Before Tuples, you did this typically with variables which you passed to a method by reference. With a reference, the method cannot only retrieve the content of the variable, the calling method can also change it. Because it is the reference which get passed – a pointer to the actual content if you will – the method can also exchange the content: When that variable gets written, that change reflects to the variable which has been passed to the method.
In C# 7, methods can turn the tables on that. C# 7 can now return references of result values, which means: When you get the result of a method by reference, your calling code can change the content where this result is pointing to. Why C#? In Visual Basic, you cannot author methods which have this ability. But as of Visual Basic 2017 you can consume reference return values. Let’s take a closer look at a sample class written in C#, which provides a method to find and replace strings in a sentence:
You see here, FindNext returns the word which matches the start characters of the search string. Since FindNext returns that element by reference, we can not only read the returned value, we can also write it.
There is one catch, though: for this to work, we need local variables which can be declared ByRef. Unfortunately, Visual Basic does not let you do this, so a code like the following, which would work – if we translated it to C# – does not so in VB:
So, can we use C# Return by Reference methods in Visual Basic at all? Yes, we can! First, we could use a method or a property returning a value ByRef in VB directly. Like this:
Looks weird, doesn’t it? How come we can assign a value to a method? That’s not supposed to work. But if you take the signature into account, by whose tooltip you can recognize a method which is returning ByRef, by the way, it starts to make sense: You’re not assigning to the method, you are assigning to the variable the return value is pointing to.
The problem still is: this is not helping us. In our example, we’re supposed to assign our replacement string back to the reference only when we know we found the correct word. But testing the word means we’re losing the reference, because there is no way to store it. Or is it?
Well, with a trick, even in Visual Basic we can declare a local ByRef variable. Visual Basic allows to pass ByRef variables to methods, so we can easily declare a helper method which takes a variable ByRef, pass the result of the C#-ByRef-Function, and use the variable the same way as we would do it in C#. Like this:
That’s exciting! This version also uses Tuples to simplify the handling. Using this helper function now becomes easy:
We’re passing the search term to FindNext. FindNext returns the found word by reference along with a status, if something has been found (in didFind), back to us, and we feed those results directly to our helper method FindNextHelper – both the stringFound reference and the didFind variable. Since FindNext changes the content of didFind by reference, this reflects to the didFind value we use inside of FindNextHelper, which we eventually return to the caller via the Tuple.
With methods like this becoming possible in C#, we will see most likely library developers using them more often. So, wouldn’t it be since, if we could come up with a more generalized form of assigning values to local reference variables in Visual Basic? Well, let’s try this:
Here, we are basically doing the same trick: We are coming up with a way to read and write to a referenced variable by moving the actual code inside a method which retrieves the pointer ByRef. And then we use a Func delegate to also pass the code which is later used to assign to the ByRef variable. In contrast to what we had before, this alternative can be used for different scenarios. Here is ours:
Don’t you think that’s pretty close to the C# version?
Well, that’s all for now.
Go and try out all the new Features of Visual Basic 2017 by yourself! And don’t forget to tell your friends and colleagues what exciting new feature there are in Visual basic 2017!
So long, with best from Germany!
(follow me on Twitter @loeffelmann)