C# 10: New features and examples that are not in C# 9

Published: Friday 20 August 2021

C# 10 development is in full swing, and we will have a look at five new C Sharp 10 features that you can try out for yourself right now!

At time of writing, C# 10 is still in preview. It is due to be released alongside the full release of .NET 6 in November 2021.

C# coding challenges

C# coding challenges

Our online code editor allows you to compile the answer.

This coincides with the Visual Studio 2022 launch, so if you wish to try out these features, you will need to download VS 2022.

At present, VS 2022 is in preview mode, so downloading Visual Studio 2022 preview will allow you try out these new features for yourself.

A number of C# 10 features are still currently in progress and won't be available until it's official launch.

However, there are plenty that have been complete and we are going to take a look at some of them now.

Feature #1: File-scoped namespace

Before C# 10, a namespace would be declared using curly braces.

// Framework.cs
namespace RoundTheCode.CSharp10.Models {
	public class Framework
	{
		public string? Name { get; set; }

		public int Version { get; set; }

		public CodingLanguage? CodingLanguage { get; set; }
	}
}

This would mean that the contents within the namespace would be indented to the right.

However, with C#10, you can now declare a file scoped namespace at the top of the file. As a result, every object within that file will belong to that namespace.

// Framework.cs
namespace RoundTheCode.CSharp10.Models;
 
public class Framework
{
	public string? Name { get; set; }

	public int Version { get; set; }

	public CodingLanguage? CodingLanguage { get; set; }
}

The benefits of having a file scoped namespace is that you are reducing horizontal waste and it looks cleaner and tidier.

Feature #2: Record structs

C# 9 saw the introduction of record classes.

C# 10 takes the record keyword further, so you can now declare a struct as a record.

One of the benefits with record classes is that they can be immutable. Below is an example of how to declare an immutable struct record, and how to initialise it.

// Framework.cs
public readonly record struct Framework(string? Name, int Version, CodingLanguage? CodingLanguage);
// CodingLanguage.cs
public readonly record struct CodingLanguage (string? Name);
// FrameworkController.cs
[Route("framework")]
public class FrameworkController : Controller
{
	[HttpGet("record-structs")]
	public IActionResult RecordStructs()
	{
		var framework = new Framework
		{
			Name = ".NET",
			Version = 6,
			CodingLanguage = new CodingLanguage { Name = "C#" }
		};

		return Json(framework);
	}
}

There is no need to declare properties in a readonly record struct. Simply pass in the property names as constructors, and it will automatic bind the property names and their values to that struct.

Feature #3: Constant interpolated strings

Interpolated strings come in handy as it means you can add an object to a string without coming out of the string.

Before C# 10, interpolated strings were perfectly acceptable when declared as a var:

var languageReleasePrefix = "C# 10";
var languageRelease = $"{languageReleasePrefix} to be released in November 2021.";
 
return Json(languageRelease);

However, if you change the personString to a const, it would throw an error.

But that's not the case with C# 10. You can now declare a interpolated string as a constant.

const string languageReleasePrefix = "C# 10";
const string languageRelease = $"{languageReleasePrefix} to be released in November 2021.";
 
return Json(languageRelease);

Feature #4: Extended property patterns

Extended property patterns makes it cleaner to do a condition on a nested property.

Take this switch example. In C# 9, you would have to wrap nested properties in curly braces:

public static string GetFullCodingLanguageName(Framework framework) => framework switch
{
	{ CodingLanguage: { Name: "C#" } } => "C Sharp",
	_ => "(unknown)"
};

But in C# 10, you now declare nested properties using a dot.

public static string GetFullCodingLanguageName(Framework framework) => framework switch
{
	{ CodingLanguage.Name: "C#" } => "C Sharp",
	_ => "(unknown)"
};

Feature #5: Global using directive

Don't you just hate having to import the same namespaces multiple times for different classes?

Well in C# 10, there is a new global keyword that allows you to declare your common namespaces in your application.

It is recommended that you create a separate file to store your global namespaces. We have created a GlobalUsing.cs file and this how it looks:

// GlobalUsing.cs
global using Microsoft.AspNetCore.Mvc;
global using RoundTheCode.CSharp10.Models;

This now means that we no longer have to declare these namespaces in each individual file.

See these new C# 10 features in action

Check out our YouTube feature where we demonstrate these features in action:

In addition, download our code example which demonstrate these features using an ASP.NET Core 6 Web API application.

More C# 10 resources

There are more C# 10 features to come before it's launch!

Check out Microsoft's "What's new in C# 10.0" article where they detail some of the new features.

In addition, there is a full list of C# 10 features in the Language Feature Status document. This document details the progress of each feature and documentation as to how each feature works.