How-To's

Named tuple inference, leading digit separator, non-trailing named arguments – VB.NET 15.3 and 15.5 language features in ReSharper and Rider

A while ago, we did a blog series about C# 7.0, 7.1, 7.2, and C# 7.3 language features. It’s high time we did something similar for VB.NET!

The latest ReSharper 2018.3 EAP and Rider 2018.3 EAP come with VB.NET 15.3 and 15.5 language support for named tuple inference, the leading digit separator, non-trailing named arguments, and the Private Protected access modifier. Let’s have a look at them, shall we?

Setting the VB.NET language version

To ensure that our project supports using these new VB.NET language features, we will have to specify the LangVersion in our .vbproj project file and either set it to one of the available VB.NET language versions (or latest):

<PropertyGroup>
  <LangVersion>15.5</LangVersion>
</PropertyGroup>

Once that is done, we can start using the latest VB.NET version in our project.

Leading hex/binary/octal digit separator

In terms of language features, let’s start with one that improves readability of our code. In Visual Basic 2017, support was added for using an underscore character (_) as a digit separator. While that improved readability, there was one place in the syntax where we could not use _: between the prefix and hexadecimal, binary, or octal digits.

In VB.NET 15.5, it is now possible to make use of the _ digit separator  there as well:

'Before:
Dim hexNumber As Integer = &HC305_F860
Dim octNumber As Integer = &O200
Dim subnet As Integer = &B11111111_1111111_11000000_00000000

'VB.NET 15.5:
Dim hexNumber As Integer = &H_C305_F860
Dim octNumber As Integer = &O_200
Dim subnet As Integer = &B_11111111_1111111_11000000_00000000

Named tuple inference

Visual Basic 2017 introduced support for tuples – lightweight structures that we can use to pass data around. Tuples are used very often when returning multiple values from a method call, without having to create a separate class to do so.

Tuples can also be used to create such lightweight data structure in code:

Dim firstName = "Maarten"
Dim lastName = "Balliauw"

Dim person = (FirstName:=firstName, LastName:=lastName)

Our person would now be a tuple with a FirstName and LastName element.

In VB.NET 15.3, creating the above tuple becomes easier. Instead of having to add the element names (FirstName and LastName): when initializing the tuple, Visual Basic will now infer the element names:

Dim firstName = "Maarten"
Dim lastName = "Balliauw"

Dim person = (firstName, lastName)

Console.WriteLine($"Person: {person.firstName} {person.lastName}")

This removes some clutter from our code, and improves readability.

Non-trailing named arguments

VB.NET 15.5 introduces support for non-trailing named arguments. They allow us to mix non-named arguments with named arguments when calling a constructor or method, as long as the order of parameters is respected.

For example, let’s assume we have a Person class defined like this:

Public Class Person
    Public Sub New(firstName As String, lastName As String, email As String, age As Integer)
        '...
    End Sub
End Class

Before VB.NET 15.5, if we did not want to pass the email argument when using this constructor, we’d write our code like this:

Dim person As New Person("Maarten", "Balliauw", Nothing, 35)

What is the argument that we are setting to Nothing here? We’d always need tooling to tell us by hovering over the call and looking at the arguments our constructor accepts.

With VB.NET 15.5, we can use named arguments anywhere in the method call, as long as we respect the order of arguments. This makes it more visible for ourselves and fellow developers to see which argument we are setting to Nothing:

Dim person As New Person("Maarten", "Balliauw", email:=Nothing, 35)

Private Protected access modifier

VB.NET 15.5 introduces a new member access modifier: Private Protected. Just like a Protected member, a Private Protected member is accessible by all members in its containing class and by types derived from the containing class.

The main difference is that Private Protected members are only accessible in their containing assembly, and not outside. In summary, that gives the following access modifiers in VB.NET 15.5 and up:

Access modifier Visibility
Public Any code that can see a public element, can access the element.
Protected Code in the class that declares a protected element, or a class derived from it, can access the element.
Friend Code in the assembly that declares a friend element, can access the element.
Private Code in the type that declares a private element, including code within contained types, can access the element.
Protected Friend Code in the same class or the same assembly as a protected friend element, or within any class derived from the element’s class, can access the element.
Private Protected Code in the class that declares a private protected element, or code in a derived class in the same assembly as the base class, can access the element.

Download ReSharper 2018.3 EAP or Rider 2018.3 EAP and give it a try! We’d love to hear your feedback!

image description