.NET 8 has been released, so it's time to start porting your projects to the new version. In this article, we'll look at new features and enhancements: C# 12, performance, Native AOT, GC, new types aimed at improving performance, NuGet Audit, and more.
We have already covered the new features of C# 12 in this article. There, we discussed new language features: primary constructors, default parameters, collection expressions, inline arrays, and so on. There aren't many major changes this time. What do you think about the update? We've looked at it and immediately got some ideas for new C# analyzer rules.
By the way, since we're talking about the analyzer, I'd like to make a small announcement. We are already working on the .NET 8 and C# 12 support. We will introduce it in PVS-Studio 7.28. The release is scheduled for early December. If you don't want to miss it, I invite you to sign up for the press-release newsletter.
Microsoft said that .NET 7, introduced last year, is very fast, but .NET 8 is faster. And that's true. Stephen Toub, in his typical fashion, told us about performance improvements in .NET 8 in the article. It's several hundred pages long and covers most (if not all) of the improvements. The following things have been enhanced: JIT, GC, reflection, collections, LINQ, code generation, serialization and deserialization, primitive data types, and much more.
The article is focused on comparing the performance of .NET 7 and .NET 8 — there are lots of comparison tables. I think everyone will find something interesting there. So, you may want to take some time off to read it.
Just a quick reminder of what the technology is: in short, Native AOT uses an ahead of time compiler to compile IL into machine code while publishing a self-contained application. .NET 8 adds support for x64 and arm64 architectures on macOS.
Native AOT applications include a .NET runtime. As a result, they are larger than regular applications. .NET 8 has enhanced this aspect as well. The table below shows the size of the "Hello World" program for both .NET 7 and .NET 8:
As you can see, the size of the application on Linux has been reduced by 50%.
Moreover, .NET 8 is starting to enable native AOT support for platforms such as iOS-like platforms. Note that this is just the beginning of the work. So, the developers ask you not to jump to conclusions about performance. You can now build and run .NET iOS and .NET MAUI applications with Native AOT on the following platforms: ios, iossimulator, maccatalyst, tvos, and tvossimulator.
.NET 8 introduces new types aimed at improving app performance in different scenarios. Developers now have the FrozenDictionary and FrozenSet collections, which are in the System.Collections.Frozen namespace. They prohibit changes to keys and values once a collection has been created. This enables them to be optimized specifically for read operations. This is a very handy feature for when a collection is filled in for the first time and stored for a long time. Here's an example of how to use the collection:
private static readonly FrozenDictionary<string, bool> _settings =
if (_settings.TryGetValue(key, out bool setting))
A new SearchValues type has been introduced. It provides an immutable, read-only set of values optimized for efficient searching.
Another new type, CompositeFormat, has been introduced specifically for cases where format strings are unknown at compile time. For example, when loading a format string from resources.
Security plays an important role in the development process, and .NET developers always remember that. Now, when running dotnet add and dotnet restore, you will get warnings about every package that contains a vulnerability.
By the way, PVS-Studio can search for vulnerable components used in your project. If the library you are using contains a vulnerable library, the analyzer will issue a warning. The analyzer searches not only for direct but also for transitive dependencies. To learn more about PVS-Studio as an SCA solution, please follow the link.
New methods for handling randomness have been added:
The GetItems method helps randomly select a specified number of items from the passed set. The Shuffle method shuffles the passed sequence of items.
As the developers say, such features will come in handy in the field of machine learning.
Starting with .NET 8, you can regulate memory limits. This feature may be useful for cloud services. For example, you can reduce the amount of memory available when the load is low. To adjust the limits, call the RefreshMemoryLimit method.
You can now also update some GC configuration settings. For example, it's possible to set a hard limit for a heap size:
With the release of the new .NET, serialization and deserialization have gotten a lot better. There are a lot of enhancements, and I'll highlight the most important ones.
So, here they are:
- improved performance;
- reduced the size of Native AOT applications that use System.Text.Json;
- added serialization support for required and init members;
- added interface hierarchy support;
- extended the JsonSourceGenerationOptionsAttribute functionality;
- added the option to disable reflection-based serialization, which is enabled by default.
You may read the following article to learn more about new features, bug fixes, and more: "What's new in System.Text.Json in .NET 8".
Looking back at the features added in .NET 7, not much seems new in .NET 8.
However, I can assure you that there are still plenty of enhancements. It seems that this time the developers focused more on targeted improvements to the platform. There are a lot of not-so-big but still important enhancements in many areas of .NET usage.
The article lists only the most interesting features that are likely to be useful to the majority of developers. You can read about all the improvements here. If you find something useful that isn't mentioned in the article, feel free to write about it in the comments.
Are you already using some of the new .NET features? Let me know in the comments!
More interesting articles you can find in our PVS-Studio blog