My Top 5 .NET 8 and C# 12 Highlights

C# Nov 7, 2023

Microsoft released .NET 8 together with C# 12 on November 14th, 2023.

Here are my five top picks from this year's release.

C# 12 – Primary Constructors

C# 12 is here.
C# 12 is here

As every recent year, Microsoft releases a new version of its programming language C# together with a new .NET version. This time it will be C# 12, and it brings many new features to the table.

One of the most discussed new features for sure is the introduction of primary constructors. Many fellow programmers have mixed feelings about this, but I can see the benefit of it, although it takes some time to get used to it.

public class User(string firstName, string lastName)
{
    // Any other constructir must be called with 'this' when using a primary constructor
    public User() : this("Franz", "Franzmann") {}
    
    public string FullName => $"{firstName} {lastName}";
}

var hans = new User("Hans", "Hansmann");
Console.WriteLine(hans.FullName)    // Hans Hansmann
    
var newUser = new User();
Console.WriteLine(newUser.FullName)    // Franz Franzmann

C# 12 – Collection Expressions

With C# 12 you can create collections very similar to TypeScript. This should increase the readability of any codebase and hopefully remove unneeded clutter.

int[] b = [ 1, 2, 3, 4, 5 ];

It's also possible to create new collections with existing collections via the spread operator.

int[] row1 = [ 1, 2, 3, 4, 5 ];
int[] row2 = [ 6, 7, 8, 9, 10 ];

int[] bothRows = [..row1, ..row2]; //1 2 3 4 5 6 7 8 9 10 

A full list of all new C# 12 features can be found here.

Performance Improvements (Again, and A lot)

Like every previous release, .NET 8 is no exclusion when it comes to performance improvements. There is a huge number of minor changes which will eventually build up to an overall faster application, quicker responses and improved startup times.‌ This text can probably be used for every .NET release announcement.

img

Stephen Tourt - MSFT has his say on all the performance improvements with .NET 8:

.NET 7 was super fast. .NET 8 is faster.

A detailed list of all the improvements is linked here. And there are many!

New Time Abstraction API

With the new TimeProvider class and ITimer interface, it will be possible to mock time easily in any test scenario. The following three essential time operations are supported.

  • Retrieve local and UTC time.
  • Obtain a timestamp for measuring performance.
  • Create a timer.

Microsoft provides the following code snippet to show the usage of the new time abstractions.

// Get system time.
DateTimeOffset utcNow = TimeProvider.System.GetUtcNow();
DateTimeOffset localNow = TimeProvider.System.GetLocalNow();

// Create a time provider that works with a
// time zone that's different than the local time zone.
private class ZonedTimeProvider : TimeProvider
{
    private TimeZoneInfo _zoneInfo;

    public ZonedTimeProvider(TimeZoneInfo zoneInfo) : base()
    {
        _zoneInfo = zoneInfo ?? TimeZoneInfo.Local;
    }

    public override TimeZoneInfo LocalTimeZone => _zoneInfo;

    public static TimeProvider FromLocalTimeZone(TimeZoneInfo zoneInfo) =>
        new ZonedTimeProvider(zoneInfo);
}

// Create a timer using a time provider.
ITimer timer = timeProvider.CreateTimer(callBack, state, delay, Timeout.InfiniteTimeSpan);

// Measure a period using the system time provider.
long providerTimestamp1 = TimeProvider.System.GetTimestamp();
long providerTimestamp2 = TimeProvider.System.GetTimestamp();

var period = GetElapsedTime(providerTimestamp1, providerTimestamp2);

New APIs for Managing Randomness

With .Net 8 anything related to randomness will be so much better than in older .Net versions. The newly introduced methods System.Random.GetItems() and System.Security.Cryptography.RandomNumberGenerator.GetItems() enables you to select a specified number of items randomly from an input set. However, the returned random entries are not unique, and the very same value can be added multiple times in the result.

using System;
					
public class Program
{
	public static void Main()
	{
		int[] numbers =  { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		var randomNumbers = Random.Shared.GetItems(numbers, 5);
		
		foreach(var item in randomNumbers)
		{
			Console.Write(item); // 55675
		}
	}
}

For that use case, you should use the System.Random.Shuffle() method as stated here so that the result has unique values. Keep in mind that Shuffle returns void, so the original collection is modified.

using System;
					
public class Program
{
	public static void Main()
	{
		int[] numbers =  { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		Random.Shared.Shuffle<int>(numbers);
		
		foreach(var item in numbers)
		{
			Console.Write(item); //512486937
		}
	}
}

A lot more

Find all the good stuff from .NET 8 here.

Happy coding as always.

Tags

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.