Top 10 .NET 9 features (with examples)


2 weeks ago, .NET 9 was released.

If you haven’t had time to read the official release docs, don’t worry.

I spent 1 hour investigating what's new in .NET 9.

So you don't have to.

Here are the top 10 improvements for C#, ASP.NET Core, and EF Core.

1. LINQ Index

LINQ has always been an extremely useful tool for .NET developers.

However, with .NET 9, LINQ comes with 3 new methods.

Let's begin with the LINQ Index.

The Index method places every collection element against its position within that collection.

It’s an excellent feature for when you want to know the index of each item:

2. LINQ AggregateBy

Suppose you want to calculate the number of seconds spent listening to each song.

Previously, you had to use the GroupBy method along with Select() for this to work.

However, with .NET 9, you can simplify this by using AggregateBy.

For instance, here we are aggregating by the Song ID and adding the total number of seconds a user listened to it:

3. LINQ CountBy

To know how many “times” a song has been listened to without using the GroupBy method, you can use CountBy.

In this example, we are counting by the “Song Name”:

4. Params Collection

The param keyword in C# allows a variable number of arguments without the need for method overloading.

It is handy when the number of inputs is not known in advance.

In previous versions of C#, the params modifier was limited to array types only.

However, with the release of C#13 and .NET 9, this keyword is now compatible with any known collections, such as Span

5. UUID Version 7

A GUID (Globally Unique Identifier) ensures that the IDs remain unique across multiple sources.

In the previous versions of C#, new rows inserted were placed in random positions, leading to index fragmentations.

However, .NET 9 has introduced GUID Version 7, which allows sequential GUIDs:

6. Lock

Instead of using the traditional System.Threading.Monitor, .NET 9 has introduced a new type called System.Threading.Lock.

With it comes the Lock.EnterScope() Method, which creates an exclusive scope and automatic release when a block of code ends.

To use the new API, you need to use the Lock object.

In this example, each thread will access the lock one after another due to mutually exclusive access.

7. Implicit Index Access

The “from the end” operator (^) has been available for quite some time.

It helps to refer to the end of collections without keeping track of indexes.

In C#13, the functionality has been extended to initializers as well, as shown below:

8. MapStaticAssets

When working on ASP.NET Core apps, you need to be able to supply static assists (JavaScript Files, CSS, etc.) to the browser.

Previously, we were using:

app.UseStaticFiles();

However, the ASP.NET Core 9 has replaced it with:

app.MapStaticAssets();

Here’s how MapStaticAssets stands out compared to UseStaticFiles:

  • Build-Time Compression: All assets in your app are compressed to minimize their size. gzip is applied during development, while both gzip and brotli are used for published builds.
  • Content-Based ETags: Each resource gets an ETag based on the SHA-256 hash of its content, encoded in Base64. This ensures the browser only downloads a file again if its content changes.

9. Hybrid Cache

Cache allows a service to store frequently needed data for short intervals, which makes the process fast and efficient.

Previous versions of ASP.NET used either Memory Cache or Distributed Cache.

HybridCache is built to replace existing IDistributedCache and IMemoryCache implementations, offering a straightforward API for adding new caching functionality.

It unifies both in-process and out-of-process caching under a single API.

10. Improved Data Seeding with EF Core 9

Before EF Core 9, data seeding was done by configuring the modelBuilder in the OnModelCreating method or in EntityTypeConfiguration.

With the improved data seeding, you now have two new methods:

  • UseSeeding()
  • UseAsyncSeeding()

You can use these methods by configuring DbContextOptionsBuilder in the OnConfiguring method:

The new seeding methods are triggered during the

  1. EnsureCreated operation,
  2. Migrate,
  3. dotnet ef database update command

even when no model changes or migrations are applied.

Therefore, a good practice is to have a check to avoid inserting duplicate records.

So, there you have it.

Thoughts on these improvements? Which one looks like the most useful to you?

Enjoy your weekend.

Kristijan

P.S.

If you:

  • fear like your development skills haven’t progressed lately...
  • are stuck in an endless cycle of using .NET Framework, Web Forms, WCF…
  • you write C# code the same way you have written 5 years ago…

Then my upcoming course "​​​​​Backend Brilliance: Architect and Build Professional .NET Applications" will be a fantastic resource for you.

Inside it:

  • You will build a real-world e-commerce ASP.NET Core 8 application.
  • Learn practical skills and industry best practices that you can use in your existing job.
  • Discover the latest .NET trends and use them when they make sense.​
  • Write secure, testable, and well-structured C# code.

You can join other .NET developers on the waitlist by clicking here.

The planned course release is at the beginning of December.

Kristijan Kralj

Weekly newsletter packed with code-improving tips, tools, and strategies to become a better .NET developer.

Read more from Kristijan Kralj

Lately, I’ve been paying more attention to what’s happening in the AI space. Maybe because of all the hype that surrounds it. Maybe because of the anxiety of whether AI will take my software development job. That's why I’ve decided to spend some spare time during the Xmas holiday to explore the state of AI software development tools. This email combines: My 1+ years of experience using a paid version of GitHub Copilot. 5+ hours of YouTube videos I’ve consumed in the last 2 weeks. So, let’s...

Today's issue is brought to you by the C# 13 and .NET 9 – Modern Cross-Platform Development Fundamentals. Build confidence in creating professional and high-performance web applications using the latest technologies in C# 13 and .NET 9 by Mark Price. Find out more here: C# 13 and .NET 9 Yesterday, We had a company Xmas party. Before dinner at a restaurant, we went to the escape room event. If you are unfamiliar with escape rooms, they're interactive puzzle experiences where you and your...

2 weeks ago, I went to sleep at the same time as my 2 kids.It sounded good on paper: Fall asleep before 9 PM. Wake up in the morning full of energy like a young bull. But in reality? I couldn’t sleep. I was tossing and turning in bed like a fish out of water.I resisted the temptation of using my phone until 10 PM. But then I started to scroll on Reddit. As I was scrolling, I found this question: “What are some of the craziest security vulnerabilities you've uncovered?” And this in particular...