What's New in Visual Basic 14 for Visual Studio 2015

Let me start with the most trivial change that's also the one you'll use the most: Right now, you type in a line of code, get a squiggly line under something indicating that you've got an error, fix the error … and then arrow off the line to see if the squiggle goes away. In Visual Studio 2015 with Visual Basic 14, you won't have to move off the line to have the squiggle go away: It will just go away.

The change you'll like best: You can view the results of a Lambda expression in Debug mode instead of getting that stupid "Evaluation of lambda expressions in this debugger" message.

Well, maybe you'll like this best: Shorter error messages in the Error List window. The Error List window, instead of showing variable names with all of their namespace prefixes, will now just use the base variable name. Your error messages might actually now fit in the Error List window.

The most important change that you should use more: Refactoring. Out of the box, C# developers have always had more refactoring support (encapsulating fields, for example) than Visual Basic developers. Now Visual Basic 14 developers get parity: select some code, right-click and select Quick Actions. A light bulb menu appears with all (and only) appropriate refactorings you can apply to the selected code.

The one you won't need very often but will really like when you do use it: Shared Projects. You can use a project's resources (source code, images, and the like) in other multiple projects.

And, finally, the one that will save you the most time: Your Visual Basic code should compile in half the time. Half. The. Time.

Posted by Peter Vogel on 05/20/20150 comments


My Favorite New Language Feature in C# 6.0 and Visual Basic 14

Both Visual Basic 14 and C# 6.0, developers get the NameOf operator/keyword. It doesn't do much: It returns the name of the variable or member passed to it. This means I can write properties that integrate with the INotifyPropertyChanged event with code like this:

Public Property CompanyName() As String 
  Get
    Return Me.companyNameValue
  End Get 
  Set
    Me.companyNameValue = value
    NotifyPropertyChanged(NameOf(CompanyName))
  End Set
End Property

This isn't going to make my applications run faster or anything useful like that. But it's going to eliminate a whole bunch of hardcoded strings in my applications that included the name of some program element. Now, instead of a string whose content the compiler couldn't validate, I can use NameOf and let the compiler check the parameter I pass.

Posted by Peter Vogel on 05/13/20150 comments


What's New in Visual Basic 14? String Interpolation and Multiline Literals

I love the String object's Format method. It's an unusual application where I'm not using it to build messages. (Long ago and far away, I used to use it to assemble SQL statements.) Typical code looks like this:

Me.txtErrorMessage.Text = 
  String.Format("You must be in {0} status to update {1}.", statusLevel, operationTarget)

In Visual Basic 14, with string interpolation, the code gets much simpler: I just put the variable name in the curly braces where I used to put the numerical place holders. The Visual Basic 14 version looks like this:

Me.txtErrorMessage.Text = 
  String.Format("You must be in {statusLevel} status to update {operationTarget}.")

Here's another string-related feature: multiline literals. In Visual Basic 14, you can split string literals over many lines without having to use the concatenation operator:

Message = "This is an unnecessarily "
          "long string that stretches "
          "over three lines with using &."

Next time, some more new favorites.

Posted by Peter Vogel on 05/12/20150 comments


New in Visual C# 6.0, Visual Basic 14: New Null/Nothing Check

I don't know how many times I've written this code like this:

if (stringVariable != null)
{
  int x = stringVariable.Length;
}

In Visual Basic I'd write this:

If stringVariable IsNot Nothing then
  Dim x as Integer 
  x = stringVariable.Length
End If

I test the string for null/nothing because if I try to get the Length of a variable set to null/Nothing ... well, I don't get the string's Length (null values don't have lengths). Instead, I get an exception.

To simplify this block of code, both C# 6.0 and Visual Basic 14 add a new operator that you can tack onto the end of a string (or other values): the question mark (?). If the string that the operator is added to is null then the expression returns null and no further processing happens.

This means that I could rewrite my previous code like this:

int x = stringVariable?.Length;

If stringVariable is set to null or Nothing, processing ends at the ? mark and no attempt is made to retrieve the Length value ... which means no exception is raised.

However, my code still isn't right because, after all, the expression with the ? operator has to return something. If my string is null then the ? operator will return null ... and my code has to handle that. The solution is to use a nullable data type to catch the result of my expression. For my example, the final code looks like this:

Dim x As Integer? = stringVariable?.Length

Two other items: First, you can use the ? operator with types other than strings. Second, if you think the ? operator is useful, consider looking at the string object's IsNullOrWhiteSpace method.

Posted by Peter Vogel on 05/04/20150 comments


What's New in C# 6.0: Selecting Exceptions in a Try...Catch Block

Visual Basic developers can put conditions on a catch block in a try...catch to control which catch block is executed when an error occurs.

With C# 6.0, C# developers can now do the same by adding a if test to the catch statement. This example checks the error message associated with the Exception object's InnerException to decide which catch block to execute:

try
{
   ...code...
 }
 catch (Exception ex) if (ex.InnerException.Message == "Parameter Error")
 {
   ...error handling code...
 }
 catch (Exception ex) if (ex.InnerException.Message == "Math Error")
 {
   ...error handling code...

How VBish is that?

Posted by Peter Vogel on 04/23/20150 comments


What's New in C# 6.0: Initialize Properties Just Like Fields

Auto-implemented properties let you define a property in a single line of code:

  public string LastName { get; set; }

In C# 6.0, you can also initialize that property to some constant value in the same statement, like this:

  public string LastName { get; set; } = "Vogel";

Yes, it's that simple.

Posted by Peter Vogel on 04/21/20150 comments


What's New in C# 6.0: Dictionary Initializers

I recently did a column about how to create a simple collection class. In that column, I discussed collection initializers which let you add items to a collection when the collection is instantiated. Here's a variation on the example I used in that column which loads two Customer objects into a List:

List<Customer> cList = new List<Customer>() {new Customer("A123"), new Customer("B246") }

Initializers are handy ... right up until you try to use an initializer with a Dictionary. The resulting code is pretty ugly:

Dictionary<string, Customer> cList = new Dictionary<string, Customer>()
{
  {"A123", new Customer("A123")},
  {"B246", new Customer("B246")}
};

Even for C#, that's a lot of punctuation marks in a very small space. C# 6.0 gives you a new syntax that saves a few keystrokes but, more importantly, makes the resulting code easier to read by eliminating some curly braces and leveraging the equals sign. The new syntax looks like this:

Dictionary<string, Customer> cList = new Dictionary<string, Customer>()
{
  ["A123"] = new Customer("A123"),
  ["B246"] = new Customer("B246")
};

That's considerably easier to read.

Posted by Peter Vogel on 04/14/20150 comments


When Indexes Are No Help

In an earlier tip I discussed how indexes can speed up processing. It's only fair that I also talk about when indexes don't help.

First: Because indexes don't always help but do always increase the time it takes to update a table (though usually by a negligible amount) you should always run a test. Before applying an index to a table, take a moment to run a query that you think your index will help run faster -- ideally, some query used in production. Run the query twice and measure how long the query takes to complete the second time. Then, after applying your index, run the query twice again and compare the results of the second run.

If you don't get a difference that you can measure with your wrist watch, drop the index: SQL Server has decided that your index isn't helpful and is ignoring it. 

Which raises the question: Why is SQL Server ignoring the index? If your table has a lot of rows and SQL Server is ignoring your index, typically the reason is that your index isn't subdividing the table sufficiently to make your index worthwhile to use.  If using the index will still require SQL Server to look at "too many" rows, SQL Server will decide it's faster to just do a scan of the whole table to find the rows it needs.

How many is "too many" will vary from one version of SQL Server to another (and other factors, including the size of the table) but SQL Server typically requires an index to return a relatively small percentage of the total number of rows in the table. This number is often as small as 20 percent -- if SQL Server has to look at more than 20 percent of your rows, SQL Server will decide that it's faster just to look at all of the rows in the table. An index on a column holding gender information (where 51 percent are F and 49 percent are M) is probably going to be ignored, for example.

Posted by Peter Vogel on 04/03/20150 comments


Configuring for a Setup Project

Eventually, it comes time to transfer your project to the production or quality assurance (QA) computer. In theory, you should just need to copy some files to the other computer. In practice, it's a lot safer to create a setup project that packages up everything you need and unpackages it on the other computer.

You do want to rebuild your setup project every time you're going to release your application; you don't need to rebuild your setup project every time you build your application. The difference between when you need to rebuild your setup project and when you don't comes down to your compile mode: Are you compiling in release mode or debug mode?

When you're working on your application, you want to compile in debug mode so that you can step through your code; when you're ready to release your application (even if it's just to the QA computer), you'll want to compile in release mode so that you get all the optimizations possible. It's only in release mode that you'll need to rebuild your setup project.

You can get Visual Studio to take care of this for you: Go to Visual Studio's Build menu and select the Configuration Manager choice. In the upper left hand corner of the resulting dialog, you'll see a dropdown list set to Debug. This indicates that the settings being displayed are the ones applied during a debug compile. Find your setup project in the list in the bottom part of the dialog and uncheck the checkbox in the Build column (you should also pick a setting for how your setup project is to be built in the Configuration column).

With your Debug settings in place, switch the dropdown list from Debug to Release. After this change, make sure that the Build option for your setup project is checked (you could also uncheck the Build option for your test project because you probably don't need to rebuild it for a release mode compile). With your release mode settings made, click the Close button to save your changes and you're done.

From now on, you just have to remember to switch the dropdown list in Visual Studio's toolbar from Debug to Release when you need a new version of your setup project (and switch the list back to Debug immediately after you generate the setup project so that you get debugging support in your compiles).

Posted by Peter Vogel on 03/19/20150 comments


Omitting and Including Debug Code

I'm working on an application that allows users to retrieve and then filter/sort their data. The rules for filtering the data seem especially bizarre to me (there are actually two sets of filters) and the users keep piling on requirements.

Since I'm modifying existing code (and don't want to take the time to rip it all out and start over again) I've been including some code to print out useful information to the Output window that helps me debug problems. I don't want this code to go into production, of course, because it would slow the application down microscopically.

I've also got to test how this whole application works based on the security of the particular user. The application determines what security to apply by reading my Windows logon Id and then validating that against a table of users. Changing my security settings would require me to log off and log back on as another user every time I wanted to run through a set of tests. To simplify testing, therefore, I've put in a backdoor that lets me arbitrarily set my security level. I really don't want that code to make it into production.

The Conditional attribute is what saves my Canadian bacon here. I simply include my offending code in a method and mark it with the Conditional attribute. I pass the Conditional attribute some test that checks a compiler variable to see if the method should be included. This example checks to see if a constant called DEBUG is present:

<Conditional("DEBUG")>
Public Sub AssignSecurity

End Sub

I use the DEBUG constant because it's automatically included by Visual Studio when you're compiling in debug mode…and automatically excluded when you compile in release mode (though you can override that).

As you can imagine, I still worry that my security bypass code will make it into production. To help ensure that it doesn't, I have another method, that puts a big red "IN TEST MODE, NOT SECURE" message on the title screen when I'm running in non-secure mode. In addition, before arbitrarily setting the security settings, my code looks for a digitally encrypted key only installed on my development machine. I still worry ... but I can live with that.

Posted by Peter Vogel on 03/11/20150 comments


Visual Studio in Full-Screen Mode

Even after you maximize Visual Studio's window you don't yet have the maximum space for working with code and the Visual Studio's visual designers. To get the maximum bit of screen real estate available, you can put your Visual Studio edit window in full-screen mode by selecting View | Full screen (or just pressing Shift+Alt+Enter). Full screen mode gets rid of the toolbars and all of your tool windows (Solution Explorer, the Toolbox, etc.); you get to keep the menu bar and the tabs for your open files (though the tabs' appearance is altered to take up less room).

When you need to get out of full-screen mode, all you have to do is click the Full Screen choice that gets added to the menu bar when you enter full screen mode.

You can still display any of the tool windows you want by selecting them from the View menu. You might also want to try memorizing the hot keys that bring up those windows, but those hot key aren't particularly obvious. It helps that the hot keys for the tool windows all begin with Control+Alt. But, unfortunately, Control+Alt+S doesn't bring up Solution Explorer as you might expect. Instead, Control+Alt+S brings up Server Explorer. To get to the Solution Explorer window, you need to use Control+Alt+L (and, no, I have no idea why). Getting to the toolbox is the equally unobvious Control+Alt+X. If there's a shortcut for Test Explorer, I haven't found it yet.

It's not my fault.

But if you're going to bang in a lot of code, it's hard to beat having all that screen real estate. If the hotkeys for the tool windows were more obvious, I'd like it even better.

Posted by Peter Vogel on 03/05/20150 comments


Leveraging Views in Entity Framework

A typical screen in your user interface probably combines data from several different tables. To handle that, I typically have my back-end processes generate Data Transfer Objects (DTOs) which combine data from several different tables. To load these DTOs with the data they need, I retrieve rows from multiple tables and pull selected columns from each table to populate the properties on my DTOs.

A reader recently pointed out to me that I could drastically simplify that retrieval code by leveraging SQL views. A SQL view pulls together multiple tables (and selected columns from those tables) into a single package. The key feature of a SQL view is that both SQL Server and Entity Framework have a great deal of difficulty in telling the difference between a view and a table.

The major difference between views and tables is that views are read-only: you can't use them to add, update, or delete rows. However, that's less of a problem than you might think, especially in Web based applications.

In an ASP.NET MVC application, for example, my code that retrieves the data to build the DTO will go in a Get method; The code to do the deletes and updates will go in Delete or Post method. While I need to retrieve data from all of the tables to build my DTO often, in my update/delete methods, I only need to work with a subset of those tables (none of the lookup tables, for example, and only those tables that the user changed). In other words, my Get and Delete/Post methods look very different, anyway.

It makes sense, therefore, to create views in SQL Server that correspond to the DTOs I will return from my back-end server. With those views in place, in my Get methods I can retrieve rows through the view with a single trip to the database. This strategy also allows SQL Server do some optimization on the retrieval which isn't possible if I retrieve the tables individually.

In Entity Framework you add a View to your DbContext object with the same code you use to add a table. This example adds a view named MySQLView to a DbContext:

Public Class AdventureWorksLTEntities 
      Inherits DbContext 
    Public Property MySQLView As DbSet(of MySQLView) 
End Class
The code to process a View is identical to the code you'd use to process a Table. You can even update the properties on View, but your code will throw an exception when you call the SaveChanges method (the message is distinctly unhelpful: It says that you can't change the property because it's part of the entity's key).

Posted by Peter Vogel on 02/25/20150 comments


Subscribe on YouTube