~/codewithstu

.NET 7: 10 New Features You Need to Know

Transcript

With .NET 7 just around the corner, we have a better idea of the features that are going to be in it. Let's take a look at 10 features you can use today. Links to all of the features can be found in the description below.

First up, we've got a new series of extensions for HttpClient. It now makes it easy for us to send PATCH requests to our endpoint. On our patch endpoint, we use the HttpPatch attribute as normal. We switch over to our calling application, we can replace the boilerplate code with a new method. Simply call PatchAsync or PatchAsJsonAsync on the HttpClient, and your request will be sent to the new patch endpoint. I'm being honest, I'm not sure why this wasn't added in the initial release, but I'm definitely glad it's in there now.

Moving on to our next feature, which is pattern matching. Pattern matching is a feature that's been around for a while now. In .NET 7, it's been updated so that we can use pattern matching with spans and strings. Let's first take a look at this feature in use with an if statement. First, we need to declare our span that we want to use in the pattern matching. Next, we write our if statement as if it was a normal pattern matching statement. If we run this, we can see that the pattern matching is working as normal. We can also use pattern matching in a switch statement. Simply pass in the span to the switch block, and you can set your case statements to utilize your string of choice. Unfortunately, this feature does not work with the new UTF-8 strings at the time of recording, but I'm hopeful that these can be implemented in the future.

LINQ has also got a small bit of love in .NET 7, and a very common operation has been added to the framework. I'm talking about ordering operations. In .NET 6 and earlier, we had to write our LINQ ordering statements with the lambda expression as shown. In .NET 7, we are now able to simplify some of our queries as we can now rewrite our OrderBy and OrderByDescending methods to a more concise Order or OrderDescending operation. This has the exact same effect but in a more concise and readable manner.

Another really cool feature of.

.NET sees some love during this next .NET release. Regular expressions are one of those things that is massively used, yet no one really knows how they work. As part of the release, regular expressions get a source generator to help us pre-compile the regular expressions so the operation does not have to be done at runtime.

In previous releases, we've had to create a static field and ensure that we passed in the Compiled flag for optimal performance. As part of the updates in .NET 7, we can now utilize the new source generator to generate our compiled regular expressions at compile time rather than on first use. Inside of a partial class, add the RegexGenerator attribute and supply your desired regex to a partial method of type Regex. Once this is done, you can invoke the method as if it was a normal function that returned your compiled regex and call the method you desire, such as IsMatch. There is also an analyzer and code fix available to help you migrate. This is one thing that I can see being heavily used in short-lived scenarios such as AWS Lambda or Azure Functions.

Regular viewers of this channel will know that I quite like OpenTelemetry as a standard and its ability to let me use .NET native technologies like Activities. As part of the updates in .NET 7, we get two new counter types: UpDownCounter and ObservableUpDownCounter. These instruments report increasing or decreasing values when the instrument is being observed. For example, we can use this new type to monitor the number of elements in a channel, as you can see in the example on screen.

In order to do this, you first need to create a Meter before calling either CreateUpDownCounter or CreateObservableUpDownCounter. The reason why we have two different versions of this instrument is because it's the difference between synchronous and asynchronous instruments in the OpenTelemetry world. Synchronous instruments are meant to be invoked in line with any business logic, meaning that they may have context associated with them. Asynchronous instruments, on the other hand, such as the ObservableUpDownCounter, only supply measurements when requested by the monitor, so naturally they are void of any context. I should also mention that if the value is monotonically increasing, just use the original counter type that's been available for a while now in.

.NET.

Next up is another feature that I think has been missing for a really long time. We've long had the ability to do caching with things like MemoryCache and distributed caching with external sources like Redis. In .NET 7, you can now retrieve the statistics of a memory cache after you enable TrackStatistics, and see the number of entries in the cache, the estimated size of the cache (assuming that you set up a size limit), the number of cache hits, and the number of cache misses. These statistics can now be written out easily via a gauge rather than having to wrap up every single cache call in custom recording code.

The next three tips are all substantial improvements to the default JSON subsystem, also known as System.Text.Json. Let's take a look at a classic polymorphic design: a base class and two derived types. To have polymorphic serialization and deserialization, we need to add the attribute JsonDerivedType to the base class. We need to do this for each of the derived classes that we want to participate in the polymorphism. This attribute takes either one or two parameters. The first parameter is required and it is the type of the derived class. The second parameter is optional and provides the framework with a way to discriminate or decide between two types during the deserialization process.

Once an object is serialized, you will see there is a special property named $type. This is the discriminator that is either generated for you or the value that you supplied in the attribute. To control what this property is called and a few other behaviors, we can apply the JsonPolymorphic attribute to the base class and set the parameter TypeDiscriminatorPropertyName. During serialization, this will be written to the value you supplied in the second parameter of JsonDerivedType.

A word of warning is needed here because the behavior isn't as intuitive as you might think. Adding these attributes isn't enough to make the feature work. You have to serialize and deserialize through the base type, otherwise this feature just will not work. I do wonder when we are going to get proper inheritance support in System.

Text.Json.

That said, we'll probably re-implement polymorphic serialization using the next new feature. We can now dynamically change what is being serialized in our JSON with the new System.Text.Json contract improvements. When we create our new JsonSerializerOptions, we can now access a new Modifier property on the TypeInfoResolver. This property allows us to set a collection of modifiers which act on each serialization, allowing us to perform several dynamic operations such as how to read or write a property, how to name the property. We can even add or remove properties or, like in this example, determine whether a property should be serialized or not depending on other properties.

The last System.Text.Json feature is not quite as cool as the previous one, but it is one that is very much needed. We can now serialize and deserialize DateOnly and TimeOnly using built-in converters. This works out of the box with no code changes required. The new numeric types such as Int128 were considered, but the team wanted to see more desire for the feature before they added support for this. However, there is already some test coverage in the code base using a custom JSON converter should you need it.

Our last feature was added back in Preview 2, and I haven't seen anything talked about this. While strictly.

.NET feature, it is an improvement to the .NET executable which we use for basically everything. We can now set up tab completion on popular shells like PowerShell and Bash. It is up to the individual .NET commands to provide the autocomplete, so this feature is only going to improve over time. Once you've got the autocomplete installed, start typing and then hit the Tab key to trigger the autocomplete.

If you enjoyed this video, consider subscribing to the YouTube channel for more content like this.

// share_this