CodeGym /Cours /C# SELF /Extension Members : propriétés

Extension Members : propriétés

C# SELF
Niveau 18 , Leçon 3
Disponible

1. Intro

Avant, tu pouvais ajouter aux classes seulement des Extension-methods. Mais ajouter une propriété (property) comme extension de classe, c’était pas possible ! Genre, si tu voulais que chaque DateTime ait une propriété IsWeekend, tu devais passer par une méthode, ce qui n’est pas toujours cool — surtout si tu veux écrire date.IsWeekend au lieu de date.IsWeekend().

Avec la sortie de C# 14, le rêve devient réalité : tu peux maintenant écrire des propriétés d’extension un peu comme les méthodes. Ça te permet d’ajouter une nouvelle propriété à un type existant sans toucher à son code source, et de les utiliser comme si c’était des propriétés normales !

Où c’est vraiment utile ?

  • Pour les types standards .NET et les libs externes dont tu ne peux pas modifier le code.
  • Pour des propriétés « virtuelles » pratiques dans les view-models, UI, vues calculées.
  • Quand tu veux une syntaxe stylée genre .SomeCalculatedProperty sans parenthèses en trop.

2. Nouvelle syntaxe dans C# 14

Dans C# 14, ils ont viré le mot-clé this pour les extensions. À la place, ils ont ajouté un opérateur spécial extension(Type this). Et avec ça, tu peux ajouter de nouveaux membres virtuels à une classe.

Ancienne syntaxe

public static class StringExtensions
{
    public static bool IsNullOrWhiteSpace(this string str)
        => string.IsNullOrWhiteSpace(str);
}

Nouvelle syntaxe


public static class Enumerable
{
    extension(TSource source)
    {
        // Membres virtuels pour l’objet
    }

    extension(TSource)
    {
        // Membres statiques virtuels
    }
}
Nouvelle syntaxe extension members (C# 14+)

Important ! Cette nouvelle syntaxe extension marche seulement avec C# 14+ et .NET 10+. Si tu utilises .NET 9, ça ne marchera pas. Mais si tu veux tester quand même, et que .NET 10 n’est pas encore sorti, installe la version .NET 10 preview 5+
Note ! Notre cours C# utilise les toutes dernières features du langage C# 14+, même celles qui sont pas encore officiellement sorties. À l’automne 2025, .NET 10 sortira, et quand tu finiras le cours, tu seras au top sur C#! 😎

3. Syntaxe des propriétés d’extension

À quoi ça ressemble ?

Imaginons que tu veux ajouter au type DateTime une propriété qui te dit si la date est un week-end :

public static class DateTimeExtensions
{
    public static bool IsWeekend(this DateTime date) => 
        date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
}

Mais ça, c’est l’ancienne version Extension Method, et tu l’appelles comme ça : myDate.IsWeekend()

Nouveau style — Extension Property


public static class DateTimeExtensions
{
    extension(DateTime source)
    {
        public bool IsWeekend // propriété d’extension !
        {
            get => source.DayOfWeek == DayOfWeek.Saturday || source.DayOfWeek == DayOfWeek.Sunday;
        }        
    }
}

Maintenant tu peux écrire :

DateTime today = DateTime.Now;
if (today.IsWeekend)
{
    Console.WriteLine("Tu peux dormir plus longtemps !");
}

4. Quels types d’extension properties existent

Tu peux ajouter non seulement des propriétés read-only, mais aussi read-write :


public static class DateTimeExtensions
{
    extension(DateTime source)
    {
        public int YearFrom1900 // propriété d’extension !
        {
            get => source.Year - 1900;
            set => source.Year = value + 1900; 
        }        
    }
}
Propriété d’extension read-write
Important : Pour les extension properties read-write, il faut piger qu’elles modifient l’objet lui-même, mais ne peuvent pas stocker une « nouvelle » valeur ailleurs (genre un champ auto). Si tu veux ajouter une propriété qui n’existe pas physiquement dans l’objet, il te faudra un storage à part (genre un dictionnaire), mais ça sort du cadre de l’utilisation de base.

5. Propriétés statiques

Grâce à la nouvelle syntaxe, tu peux ajouter des propriétés virtuelles non seulement à l’objet, mais aussi à la classe ! Oui, t’as bien compris, maintenant on peut ajouter des propriétés statiques virtuelles à une classe. La syntaxe est quasi la même :


public static class DateTimeExtensions
{
    // Nouvelle syntaxe : extension block pour DateTime (C# 14)
    extension(DateTime)
    {
        // Propriété statique pour stocker le fuseau horaire courant de l’utilisateur
        private static TimeZoneInfo _currentTimeZone = TimeZoneInfo.Local;

        // Propriété d’extension pour accéder au fuseau horaire courant
        public static TimeZoneInfo CurrentTimeZone
        {
            get => _currentTimeZone;
            set => _currentTimeZone = value ?? TimeZoneInfo.Local;
        }

        // Retourne l’heure dans le fuseau horaire utilisateur
        public DateTime InCurrentTimeZone
        {
            get => TimeZoneInfo.ConvertTime(this, CurrentTimeZone);
        }
    }
}

6. Exemples : on étend la classe Dog !

On continue à faire évoluer notre appli avec les chiens, qu’on traîne de conf en conf.

Imaginons que maintenant on a non seulement des chiens, mais aussi une liste de leurs vaccins (List<DateTime>), mais la classe Dog vient d’une lib externe, donc on ne peut pas toucher à son code. On veut ajouter une propriété : Est-ce que tous les vaccins nécessaires ont été faits cette année ?

Ancienne méthode (extension method) :

public static class DogExtensions
{
    public static bool AllVaccinatedThisYear(this Dog dog)
    {
        return dog.Vaccinations.Any(v => v.Year == DateTime.Now.Year);
    }
}
// Utilisation :
if (myDog.AllVaccinatedThisYear())
    Console.WriteLine("Le chien est en bonne santé !");

Nouvelle méthode (propriété d’extension) :


public static class DogExtensions
{
    extension(Dog)
    {
        public bool AllVaccinatedThisYear
        {
            get => Vaccinations.Any(v => v.Year == DateTime.Now.Year);
        }
    }
}

// Utilisation :
if (myDog.AllVaccinatedThisYear)
    Console.WriteLine("Le chien est en bonne santé !");

Exemple complet

// Classe Dog — par exemple, d’une lib externe :
public class Dog
{
    public string Name { get; set; }
    public List<DateTime> Vaccinations { get; set; } = new List<DateTime>();
}

// Classe d’extensions avec extension block :
public static class DogExtensions
{
    extension(Dog)
    {
        public bool AllVaccinatedThisYear
        {
            get => Vaccinations.Any(v => v.Year == DateTime.Now.Year);
        }
    }
}

// Dans le programme :
var myDog = new Dog { Name = "Buddy" };
myDog.Vaccinations.Add(new DateTime(DateTime.Now.Year, 2, 16)); // vaccin cette année

Console.WriteLine($"{myDog.Name}: vacciné ? {(myDog.AllVaccinatedThisYear ? "Oui" : "Non")}");

7. Tableau : Extension methods vs Extension properties

Extension method Extension property
Syntaxe d’appel obj.Method() obj.Property
Passe des paramètres Oui Non (juste this obj)
Peut être assignée Non applicable Seulement si implémenté
Pratique pour View/UI Parfois Oui (binding bidirectionnel, lambda)
Visible en réflexion Non Non

8. Pièges potentiels et erreurs classiques

Quand les extension properties ne servent à rien

  • Elles ne peuvent pas remplacer complètement les vrais champs : elles n’ont pas accès aux membres privés de l’objet.
  • Impossible d’ajouter un changement automatique d’état de l’objet (genre, tu ne peux pas suivre le changement de valeur dans la classe d’origine direct).
  • Impossible d’utiliser une extension property pour implémenter une interface ou une classe abstraite.

Erreur de nommage

Si jamais la classe d’origine reçoit une propriété avec le même nom que la tienne, c’est la propriété « native » qui sera utilisée, pas ton extension. Donc fais gaffe au choix des noms, surtout avec les types publics de .NET.

Problèmes de sérialisation/réflexion

Une extension property, ce n’est pas un « vrai » membre du type, juste du sucre syntaxique. Donc, si tu utilises la réflexion ou la sérialisation, la propriété d’extension risque de ne pas être visible pour ces outils.

2
Mission
C# SELF, niveau 18, leçon 3
Bloqué
Création d'une propriété d'extension pour vérifier si une année est bissextile
Création d'une propriété d'extension pour vérifier si une année est bissextile
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION