P M A J E W S K I

Please Wait For Loading

Discover What’s New in C# 13: Exciting Features and Enhancements - Software Developer's Tour

    You Are Currently Here!
  • Home
  • News.NETDiscover What’s New in C# 13: Exciting Features and Enhancements
C#13 incoming

Discover What’s New in C# 13: Exciting Features and Enhancements

.NET 9 was released on May 21, 2024.

.NET 9 was released on May 21, 2024.

A while ago, we talked about the new features introduced in .NET 8 – a worthy successor to .NET 6?

It hasn’t been long, and we already have .NET 9. Let’s talk about new interesting features.

How to test C# 13 (.NET 9)?

Normally, when we try to build application

compiler error

We will get an error 

Following error message we have to change .csproj file

Original .csproj file

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Final version

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <LangVersion>Preview</LangVersion>
  </PropertyGroup>

</Project>

After this modification, the application builds successfully.

build success

Implicit index access

This feature is useful when we are using arrays with a known size. 

The code

var test = new Test
{
    Array = {
        [^4] = 0,
        [^2] = 1,
        [^3] = 2,
        [^1] = 3,
    },
    Array2 = {
        [2] = 0,
        [0] = 1,
        [3] = 2,
        [1] = 3,
    }
};

test.Array.ToList().ForEach(x => Console.Write(x));
Console.WriteLine();
test.Array2.ToList().ForEach(x => Console.Write(x));

class Test { 
    public int[] Array = new int[4];
    public int[] Array2 = new int[4];
}

Until now, we could do something like this.

    Array2 = {
        [2] = 0,
        [0] = 1,
        [3] = 2,
        [1] = 3,
    }

But now we are available to do something like this

Array = {
        [^4] = 0,
        [^2] = 1,
        [^3] = 2,
        [^1] = 3,
    }

Python provides elements from the end of a collection by using negative indices (-1, -2, etc.). In C#, we can do the same by using the “^” operator, but until now we weren’t able to use it in initializer expression.

I don’t know of any case where I would use it, but now this limitation is gone.

Enhancements to Extensions

The code

var square1 = new Square {
    A = 2
};

Console.WriteLine(square1.CalculateArea());
Console.WriteLine(square1.CalculateDiagonal());

class Square { 
    public int A { get; set; }
}

static class TestExtensions {
    public static int CalculateArea(this Square square) {
        return square.A * square.A;
    }

    public static double CalculateDiagonal(this Square square) {
        return square.A * Math.Sqrt(2);
    }
}

Above is a simple example of existing extensions. What improvements can we make in .NET 9 and C# 13?

The CalculateArea method is good, and we have nothing to change here.

The CalculateDiagonal method would be clearer and more intuitive if it were a property, not a method. With C# 13 we can do that!

The code

var square1 = new Square {
    A = 2
};

Console.WriteLine(square1.CalculateArea());
Console.WriteLine(square1.CalculateDiagonal());
Console.WriteLine(square1.Diagonal);

public class Square 
{ 
    public int A { get; set; }
}

public implicit extension SquareExtensions for Square
{
    public double Diagonal => this.A * Math.Sqrt(2);
}

static class TestExtensions 
{
    public static int CalculateArea(this Square square) {
        return square.A * square.A;
    }

    public static double CalculateDiagonal(this Square square) {
        return square.A * Math.Sqrt(2);
    }
}

This part of code extends the Square class with an attribute called Diagonal. What’s interesting is that we can extend everything, even types not owned (for example, from NuGet packages).

public implicit extension SquareExtensions for Square
{
    public double Diagonal => this.A * Math.Sqrt(2);
}

You can track the progress on Language Feature Status

leave a comment