Visual Basic 14 Inline Comments

I'm not a big fan of commenting code, which means that when I feel the need to add a comment it's because I feel that the comment is critical to the code's future. As a result, I want any comments I add to have maximum impact/usefulness.

In Visual Basic, however, I can only put comments before or after the statements that I want to comment. This is especially limiting in LINQ queries, which I often break up over multiple lines, putting each LINQ clause on a different line. This means that a comment on the line before the LINQ query may be explaining something three or four lines farther down the screen. 

With Visual Basic 14, I can finally put my comments where I want them: In-line with the part of the LINQ query I want to explain. This example uses a comment to explain a Where clause:

  Dim PremCusts = From c In db.Customers
                  Where c.Id % 2 = 0    'Premium customers have an even numbered id
                  Select c

You can also use in-line comments when you break up a statement over multiple lines using implicit line continuation.

Posted by Peter Vogel on 06/09/2015 at 8:31 AM0 comments


What's New in Visual Basic 14: ReadOnly Auto-Implemented Properties

In Visual Basic 14, can now have read-only auto-implemented properties: Just add the ReadOnly keyword to the Property declaration. Here's an example:

Class Customer
   Public ReadOnly Property Id As String

You can set the property by name from within your class' constructors. This example sets my Customer's Id property:

Sub New(Id As String)
  Me.Id = Id
End Sub

From elsewhere in your class, you can not set the property's value using the property's name. This code won't work anywhere outside of the class' constructor:

Me.Id = Id

However, you can access the backing field for the property and set the property's value through that. The backing field will have the same name as the property with an underscore prefixed to the property name.

This example updates my read-only Id property through its backing field:

_Id = "Fred"

On a related note: If you have an interface that specifies that a property is read-only, in Visual Basic 14 you don't have to honor that restriction when you implement the interface in a class. The interface that specifies a ReadOnly property will be happy with either a read-only or a read-write implementation in the class that implements the interface.

Posted by Peter Vogel on 05/29/2015 at 11:01 AM0 comments


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/2015 at 1:44 PM0 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/2015 at 9:59 AM0 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/2015 at 10:12 AM0 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/2015 at 11:05 AM0 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/2015 at 10:49 AM0 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/2015 at 2:01 PM0 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/2015 at 12:46 AM0 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/2015 at 2:23 PM0 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/2015 at 9:26 AM0 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/2015 at 2:24 PM0 comments


Upcoming Events

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.