LE 28/10/2025 — 2 MINUTES DE LECTURE

Les nouveautés de C# 14

À quelques jours de la sortie de .NET 10, faisons ensemble le point sur les toutes dernières nouveautés de C# 14, en explorant les nouvelles fonctionnalités du langage.

Les nouveautés de C# 14

Vous n’avez peut‑être pas encore intégré toutes les nouveautés de C# 11, 12 ou 13 à vos habitudes de développement (c’est mon cas), qu’une nouvelle version de .NET pointe déjà le bout de son nez (comme chaque année en novembre). À l’heure où j’écris ces lignes, la release candidate 2 de .NET 10 (LTS) est disponible au téléchargement. Les fonctionnalités de C# 14 étant désormais figées, c’est l’occasion de faire le point sur les derniers ajouts intéressants du langage, avec quelques exemples de code.

 

Le mot clé field

C’est probablement la fonctionnalité la plus intéressante de cette version. Pour les propriétés complètes, un nouveau mot-clé fait son apparition : il s’agit de field. Son utilisation permet de se passer du champ de sauvegarde privé que l’on avait l’habitude d’associer à la propriété. Le compilateur va quand même générer un champ, mais l’avantage c’est qu’on pourra l'exploiter librement.

// C# 13
public class Blog
{
    private int _visits;

    public int Visits
    {
        get;
        set
        {
            if (value > 2)
                Console.WriteLine("Wouah, Unbelievable !");
            _visits = value;
        }
    }
}

// C# 14
public class Blog
{
    public int Visits
    {
        get;
        set
        {
            if (value > 2)
                Console.WriteLine("Wouah, Amazing !");
            field = value;
        }
    }
}

 

Les membres d'extensions

Depuis C# 3, il est possible d’étendre un type sans le modifier grâce aux méthodes d’extension. Avec C# 14, Microsoft généralise le concept et offre un peu plus de souplesse en permettant d’ajouter n’importe quel type de membre (propriétés, méthodes statiques, opérateurs…). Cela passe par une nouvelle syntaxe avec le mot-clé extension suivi du type. L’ancienne syntaxe avec this reste toujours valable.

// C# 13
public static class BlogExtensions
{
    public static void PrintVisits(this Blog blog)
    {
        Console.WriteLine("Nombre de visites : " + blog.Visits);
    }
}

// C# 14
public static class BlogExtensions
{
    extension(Blog blog)
    {
        // Propriété d'extension
        public bool IsPopular => blog.Visits > 100;

        // Méthode d'extension
        public void PrintVisits()
        {
            Console.WriteLine("Nombre de visites : " + blog.Visits);
        }
    }
}

 

Opérateur pour une affectation conditionnelle

Désormais, il est possible d’ajouter l’opérateur ? du côté gauche d’une affectation, ce qui permet, par exemple, de se passer de l’utilisation d’un if pour vérifier un nullable.

Blog? blog = null;

// C# 13
if (blog is not null)
{
    blog.Visits = 10;
}

// C# 14
blog?.Visits = 10;

public class Blog
{
    public int Visits { get; set; }
}

En C# 14, la propriété Visit ne sera affectée à 10 que si la variable locale blog n’est pas null

À noter que cela fonctionne aussi avec des opérateurs composés comme += et -=, mais pas avec ++ ou --.

// Corect
blog?.Visits += 1;

// Incorect
blog?.Visits++;

 

Générique et nameof()

L’utilisation de nameof sur des types génériques fait l’objet d’améliorations dans cette dernière version. Auparavant, il était nécessaire de qualifier explicitement le type générique pour obtenir un résultat. Désormais, ce n’est plus obligatoire.

Console.WriteLine(nameof(List<int>));  // C# 13, qualification du générique obligatoire
Console.WriteLine(nameof(List<>)); // C# 14

 

Lambda et modificateurs

Les lambdas autorisent d’utiliser des modificateurs de paramètres (comme ref, out ou in) sans préciser le type si le contexte (delegate ou expression) le connaît déjà.

delegate bool TryParse<T>(string text, out T result);

// C# 13
TryParse<int> parse = (string text, out int result) => Int32.TryParse(text, out result);

// C# 14
TryParse<int> parse = (text, out result) => Int32.TryParse(text, out result);