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

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.

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.

Posted in Hosting Article.