4 min read

Unveiling .NET 9: Enhancements, Quality Assurance, and Understanding

This article explores vital improvements in .NET 9 with practical code examples and clarify the distinctions between STS and LTS releases.
Unveiling .NET 9: Enhancements, Quality Assurance, and Understanding

On November 12, 2024, Microsoft unveiled .NET 9, marking it as a Standard Term Support (STS) release. This iteration introduces several enhancements over .NET 8, reinforcing the consistent quality across STS and Long-Term Support (LTS) versions.

This article explores vital improvements in .NET 9 with practical code examples and clarifies the distinctions between STS and LTS releases.

Get .NET 9

You can download .NET 9.0 from the official Microsoft .NET website. This page provides installers for various operating systems, including Windows, macOS, and Linux.

For Windows users, the installation process is straightforward:

  1. Download the Installer: Visit the Download .NET 9.0 page and select the appropriate installer for your system architecture (x64, x86, or Arm64).
  2. Run the Installer: Once downloaded, execute the installer and follow the on-screen instructions to complete the installation.

New C# Version

.NET 9 includes C# 13, introducing several enhancements to improve code clarity, maintainability, and developer productivity. Key features include:

  • params Collections: The params keyword now supports various collection types beyond arrays, allowing methods to accept a flexible number of arguments.
using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        PrintNumbers(1, 2, 3, 4, 5);
        PrintNumbers(new List<int> { 6, 7, 8, 9, 10 });
    }

    public static void PrintNumbers(params IEnumerable<int> numbers)
    {
        foreach (var number in numbers)
        {
            Console.WriteLine(number);
        }
    }
}
  • New Lock Type: A new Lock type offers improved thread synchronization, enhancing performance and reliability in concurrent applications.
using System;
using System.Threading;
using System.Threading.Tasks;

public class Program
{
    private static Lock myLock = new Lock();

    public static async Task Main()
    {
        await Task.WhenAll(Task1(), Task2());
    }

    public static async Task Task1()
    {
        using (myLock.EnterScope())
        {
            Console.WriteLine("Task1 acquired the lock.");
            await Task.Delay(1000);
            Console.WriteLine("Task1 released the lock.");
        }
    }

    public static async Task Task2()
    {
        using (myLock.EnterScope())
        {
            Console.WriteLine("Task2 acquired the lock.");
            await Task.Delay(1000);
            Console.WriteLine("Task2 released the lock.");
        }
    }
}
  • Escape Sequence \e: The addition of the \e escape sequence represents the ASCII escape character, simplifying the inclusion of this character in strings.
using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("\e[1mThis is bold text\e[0m");
    }
}
  • Method Group Natural Type Improvements: Enhancements in method group conversions lead to more intuitive type inference and overload resolution.
using System;
using System.Linq;

public class Program
{
    public static void Main()
    {
        Func<int, bool> isEven = IsEven;
        var numbers = Enumerable.Range(1, 10);
        var evenNumbers = numbers.Where(isEven);

        foreach (var number in evenNumbers)
        {
            Console.WriteLine(number);
        }
    }

    public static bool IsEven(int number) => number % 2 == 0;
}
  • Implicit Indexer Access in Object Initializers: You can now use indexers within object initializers, streamlining the initialization of collections and arrays.
using System;

public class Program
{
    public static void Main()
    {
        var arrayHolder = new ArrayHolder
        {
            Numbers = { [^1] = 99 }
        };

        foreach (var number in arrayHolder.Numbers)
        {
            Console.WriteLine(number);
        }
    }
}

public class ArrayHolder
{
    public int[] Numbers { get; set; } = new int[5];
}
  • ref Locals and Unsafe Contexts in Iterators and Async Methods: The language now supports ref locals and unsafe contexts within iterators and asynchronous methods, providing greater flexibility in performance-critical scenarios.
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main()
    {
        await foreach (var number in GetNumbersAsync())
        {
            Console.WriteLine(number);
        }
    }

    public static async IAsyncEnumerable<int> GetNumbersAsync()
    {
        int[] numbers = { 1, 2, 3, 4, 5 };

        for (int i = 0; i < numbers.Length; i++)
        {
            yield return numbers[i];
            await Task.Delay(100);
        }
    }
}
  • ref struct Types Implementing Interfaces: ref struct types can now implement interfaces, expanding their usability in various design patterns.
using System;

public interface IProcess
{
    void Execute();
}

public ref struct Processor : IProcess
{
    public void Execute()
    {
        Console.WriteLine("Processing...");
    }
}

public class Program
{
    public static void Main()
    {
        Processor processor = new Processor();
        processor.Execute();
    }
}

Key Improvements in .NET 9

1. Enhanced Asynchronous Programming in Windows Forms

.NET 9 introduces asynchronous dialog support in Windows Forms, allowing developers to display modal dialogs without blocking the main thread.

Example:

using System;
using System.Threading.Tasks;
using System.Windows.Forms;

public class MainForm : Form
{
    private async void ShowDialogButton_Click(object sender, EventArgs e)
    {
        using (var dialog = new CustomDialog())
        {
            await dialog.ShowDialogAsync(this);
        }
    }
}

This feature enhances application responsiveness by preventing the UI from freezing during dialog operations.

2. Optimized Static File Handling in ASP.NET Core

ASP.NET Core in .NET 9 offers optimized handling of static files, such as JavaScript and CSS, during the build and publish processes. This includes automatic fingerprinted versioning, which aids in cache busting and ensures clients receive the latest file versions.

Example:

app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        ctx.Context.Response.Headers.Append("Cache-Control", "public,max-age=31536000");
    }
});

This configuration sets long-term caching for static files, with automatic versioning ensuring clients always fetch the most recent versions.

3. Introduction of the HybridWebView Control in .NET MAUI

.NET Multi-platform App UI (.NET MAUI) in .NET 9 introduces the HybridWebView control, facilitating the integration of JavaScript-enabled content from frameworks like ReactJS, Vue.js, and Angular into .NET applications.

Example:

<HybridWebView Source="https://example.com" />

This control enables developers to embed rich web content seamlessly within their applications.

Quality Assurance in STS and LTS Releases

Microsoft maintains a consistent quality standard across both STS and LTS releases. The primary distinction lies in the support duration:

  • STS Releases: Supported for 18 months, targeting users who prefer early adoption of new features and improvements.
  • LTS Releases: Supported for 3 years, catering to users prioritizing extended support and stability.

Both release types undergo identical engineering and release processes, ensuring security, compatibility, and reliability parity. The main differences between STS and LTS releases are:

  • Support Duration: STS releases receive 18 months of support, while LTS releases are supported for 3 years.
  • Release Cadence: STS releases are issued in even-numbered years, and LTS releases in odd-numbered years.

This structured approach allows organizations to choose between rapid feature adoption with STS releases or prolonged stability with LTS releases, depending on their operational needs.

In summary, .NET 9 as an STS release brings significant enhancements over .NET 8, focusing on maintaining high-quality standards. Understanding the distinctions between STS and LTS releases enables developers and organizations to make informed decisions aligned with their development strategies.