Countdown to C# 8: Visual Studio 2019 first impressions and non-nullable reference types

Akos Nagy
Mar 11, 2019

The launch of Visual Studio 2019 is upon us — and with the new IDE, we also get a new compiler for the newest version of our favorite programming language. There are already a lot of reviews and previews about the features that are available in the preview, but I decided I would share my own opinions about them (trust me, I'll have things that I can share).

To warm up, I decided to present a feature of C# 8 that's been out there for a while now: non-nullable reference types. But before I dive into it, here are a couple of first impressions of the new and improved Visual Studio. Nothing fancy, just the things that really popped out (I'm not really into IDE feature reviews anyway).

So what's new in Visual Studio 2019?

Well, you will definitely notice the new splashscreen:

Verdict: I like it. Doesn't really mean anything, but it's nice :)

When the IDE starts up, you'll get an entirely different experience than before. This is the actual first screen:

Verdict: Not sure. It's nice and clean, but I did like the feed from the different Microsoft blogs built-in (maybe I was the only one?). Also not sure how this will play with extensions targeting the start page of previous editions and how much work it will be to rewrite them.

If you decide to create a new project, the dialog looks like this:

Verdict: This is simply just nice.

When I started up Visual Studio, there were two other things that hit me. One of them was that the 'Quick launch' got moved and in its regular place I saw 'Live share':

Verdict: I have to say, I'm ambivalent. 'Quick launch' is probably one of the features I'm using the most, so I'm not to happy that it has been moved. But live share is probably the best thing since sliced bread, so it's cool to have tha available.

And when I started coding, I saw that the keywords for control structures are now highlighted with purple :)

Verdict: Again, nothing special, but I like it.

Of course there are other, more important features of the new IDE than these (like IntelliCode). I will probably leave their dicussion to more experienced and invested people. I did say first impressions :) So now after the first impressions, let's dive into the new C# feature.

Non-nullable reference types

Again, we've known about this feature for a while and there hasve been numerous previews to try. If you do a websearch, you'll probably get a million hits (this one or this one are especially good, I think), so I don't want to increase the entropy of the web further. Just a couple thoughts.

So the feature basically gives you warnings for potential null-reference errors. You have to enable it with a switch in the .csproj file for now, and after you do, if you have a little piece of code like this:

string s = null; 
int j = s.Length;

The first line gives you the warning "converting null literal or possible null value to non-nullable type" and the second "possible dereference of a null reference". So basically this means that from now on, when you declare something as string, it cannot contain a null value. To make the variable nullable again, you have to use string?.

string? s = null; 
int j = s.Length;

In this case, the first line is now warning free, but the second still warns you about possible null-reference error. You can change the int to int? and use the Elvis-operator as an option. Another option is to add explicit null-check:

if (s != null)
{
  int j4 = s.Length;
}            

And another is to use another version of the member-access operator, !..

string? s = null; 
int j = s!.Length; // The warning's gone, but this gives you a runtime error, of course.

One could say that tools like Resharper have known this for a long time. And partially, this is true. But only partially. For one thing, you do not have to spend an awful lot of money and an awful lot of memory for this. Second, this is now the default (when you add the switch to the .csproj file). That means no attributes, no other magic. And third, it works for array element types or generic closing types as well. And that's super awesome :) This code gives you a warning:

List<string> x = new List<string>();
x[0] = null;

While this is fine:

List<string?> x = new List<string>();
x[0] = null;

Very cool. And of course, there are the edge cases. This code is fine, for example:

string? s = null;
if (!string.IsNullOrEmpty(s))
{            
  int j5 = s.Length;
}

The compiler has implicit knowledge about certain, "well-known" methods, like string.IsNUllOrEmpty() or the assertion-like methods and correctly infers that there is no chance for a null-reference exception here. But for now, you cannot create methods like this yourself. There was talk about adding a way to somehow indicate these special methods, but as for now, this option is not available.

Verdict: This is a very cool feature. I like how it is built-in, you do not need any extra addins. It is also very nice that this is the default (meaning that string is non-nullable, like int, and string? is nullable, like int?). I definitely think that this will make the quality of our code a lot better. I'm still waiting for a way to somehow hook into this feature and define methods like string.IsNullOrEmpty() myself, but for now, I am more than content.

Akos Nagy
Posted in C# Visual Studio