C# 8.0 in Visual Studio 2019: what's new

Akos Nagy
Apr 6, 2019

This week VS 2019 finally came out and I was going to write a very enthusiastic and very long post about the new language features of C# 8 that I was hoping would also premier with the new IDE. Well, I was wrong on all counts: no new language version, so no long post. But we do have a couple of new features that you can use with this edition, so I will look into those briefly.

What we've already had

I have written a couple of posts about the new language features that were also part of the previews, you can check them out if you want:

One extra thing that was not in the previews is null-coalescing assignments. With C# 8.0, you can now write this:

string x = null;
string y = "Akos";
x ??= y;

This last line means 'assign y to x if x is null'. I guess it's kinda cool, even if it won't change the world :)

What we've already (?) had

So when I went through all the new language features, I came across the improved pattern-matching capabilities. Here's the thing: I hate pattern matching. I think it promotes writing ugly and badly OO code. While it is useful in other types of languages, I think they shouldn't be part of C#. And I also discourage people to use it in testable business logic code. So I won't cover the improvements here either; if you are very keen on seeing how they work, check out this post by Mads Torgersen.

But here's the thing: the previous post actually claims that other language features of C# have been available in the previews. And if he says so, I must be so. But I haven't seen them in action yet, so they are new to me, so it's worth posting a short article about them (except for the pattern-matching).

So one cool thing is the feature known as "using declaration". With this you can write code like this:

using var writer = new StreamWriter("output.txt");
writer.WriteLine("Some content");

And whenever writer goes out of scope (i.e. end of the block it's declared in), the Dispose() method gets called, just like with the regular using. Cool.

Another cool thing is that now the local functions can be amended with the static modifier. In that case it means that the local function cannot access the containing functions local variables. To be honest, I don't really use local functions that much, but this is a nice little addition.

And one last thing that I don't think many people will use either, but it's cool from a technical standpoint. Ref structs were introduced in C# 7.2. One of the main constraints of these types is that they must not be placed on the heap. So obviously, they cannot implement interfaces either. But sometimes, you might want to make them disposable and use them in a using block, but this was not possible, since they cannot implement interfaces. Well, not anymore. They still cannot implement interfaces, but you can simply add a public void Dispose() method to them. And the best part is that even though they are not really IDisposable, you can still use them in a using block — or with the new using declaration feature.

The countdown continues

So I guess the countdown continues. Maybe with the release of .NET Core 3 we will get the new language version, since many features build on top of that. For now, I guess I'll just have to wait for the target-typed new and the default interface implementation features.

Akos Nagy
Posted in C#