Home C# 8.0 - What's New

C# 8.0 - What's New

Together with .NET Core 3.0, Microsoft released C# 8.0. Today, I want to take a look at the new features of C# 8.0 using .NET Core 3.0.

To follow along with the demo you need Visual Studio 2019 and .NET Core 3.0. You can find the code of the demo on GitHub.

Nullable Reference Types

Avoiding NullReferenceExceptiony can be hard. Therefore C# 8.0 introduces nullable reference types which help us to avoid null reference mistakes at compile-time. This new feature allows you to mark properties as nullable and non-nullable. For example, you can have nullable and non-nullable strings now.  Let’s see some code:

I have created a new class, Car, with two string properties.

Implementation of the Car class

Implementation of the Car class

I expected the compiler to give me a warning that Brand and Make could be null. But everything seems fine. Nullable Reference Types are an opt-in feature. This means that you have to enable the feature to be able to use it. It should be enabled for new C# 8.0 projects, but it didn’t work for me. To enable it add netcoreapp3.0 to the PropertyGroup of your .csproj file.

Enable Nullable Reference Types for your C# 8.0 project

Enable Nullable Reference Types for your C# 8.0 project

After adding this tag, you will see two compiler warnings and visual effects under the properties.

Warning of uninitialized properties

Warning of uninitialized properties

If you want them to be null, you can use the Elvis operator to mark them as nullable. This removes the compiler warning.

Mark the properties as nullable

Mark the properties as nullable

Another useful feature is that the compiler warns you of possible null reference exceptions when you use a nullable property. In the following screenshot, I try to access the Length of the Make property. Since I haven’t initialized the Make property, this would lead to a NullReferenceException.

NullReference warning from the compiler in the code

NullReference warning from the compiler in the code

The compiler is great but not perfect. Sometimes a property can’t be null but the compiler still gives you the warning. Then you can tell the compiler that this property is never null by using the ! operator.

Telling the compiler that a property is never null

Telling the compiler that a property is never null

In this case, you shouldn’t use it though because the compiler is right and the property is null.

Pattern Matching

Pattern matching was first introduced in C# 7. C# 8.0 extends the pattern matching by allowing us to use more types of patterns in more places.

Property Patterns

Property patterns allow you to check one or multiple properties of an object and return a value, depending on the properties. In my example, I have a house class with a name and floors. If the house has exactly 10 floors and is named Skyscraper, I return true. Otherwise, I return false. This is not the best example but I am not really good at coming up with examples 😉

Property Pattern Matching in C# 8.0

Property Pattern Matching

Switch Expressions

This feature allows you to switch over objects and return different values, depending on the type of the object and additionally on the properties of the example. For this demo, I created three classes, Circle, Rectangle and Triangle. I pass the object to a method and the method returns information about the object, depending on its type.

Switch Expressions

Switch Expressions

On the screenshot above, you can see the switch statement for my three different objects. You can also have a switch in a switch. I use this to return a different text if the object is a normal rectangle or a square. The switch expression doesn’t allow a fall-through, the, therefore no break is needed after the case. The last line handles the default case, using the _ to catch all cases which weren’t handled before.

Nesting switch statements in the switch can be handy but don’t overdo since your code can become hard to read very fast.

Tuple Patterns

Tuple patterns are similar to switch expressions. Here you can pass two values (a tuple) which are evaluated in the case. In my demo, I pass two colors and return the result if you mix these two colors. For example, red and blue will lead to purple.

Tuple Patterns in C# 8.0

Tuple Patterns

The last two lines are interesting. The second last line, (_, _) when color1 == color2 doesn’t care which colors are passed, as long as both have the same value. The last one works as the default case and returns unknown when no case was hit before.

Indices and Ranges

Working with indices and ranges can be confusing. I am gonna try to explain them first before I show a code demo. C#8.0 provides the new range operator .. which allows you to work with ranges. For example, you can have an array with ascending numbers from 1 to 10. With the range operator, you could select all items from index 2 to 8. It is important to note that the beginning of a range is inclusive and the end is exclusive. This means the range [1..8] returns the numbers 2 – 8. This is due to the previously mentioned inclusion of the beginning and exclusion of the end. Additionally, C#, like many other languages is zero index-based. This means that index 1 will give you the second number, therefore 2.

You can select an index based on the beginning of the array but also based on the end of the array. To use an offset of the end of the array, use the ^ operator. For example [^1] will give you the last number of the array. Note that [^0] will lead to an index out of range exception because it works the same way as array.Length. This would also give you an out of range exception due to the zero-based indexing.

Let’s code some examples which should make this feature clearer.

Additional C# 8.0 Features

C# 8.0 brings too many new features to highlight here. Additional features are:

  • Default Interface Members
  • Using Declarations
  • Async Streams
  • Static Local Functions
  • Disposable ref Structs
  • Many more

For more information about the new features of C# 8.0 see Microsoft’s documentation.


In this post, I presented some of the new features of C# 8.0 like nullable reference types, pattern matching, and async streams. There are many more new features that you can look into in detail in the official documentation.

You can find the code of today’s demo on GitHub.

This post is licensed under CC BY 4.0 by the author.

Create Policies for your Branches in Azure DevOps

.NET Core 3.0 - What's new

Comments powered by Disqus.