CodeGym /Cours /C# SELF /Membres statiques dans les interfaces

Membres statiques dans les interfaces

C# SELF
Niveau 24, Leçon 1
Disponible

1. Intro

À l’époque, les interfaces étaient strictes comme un règlement d’internat : que des signatures, pas de champs, pas d’implémentation, pas de membres statiques ! Mais .NET évolue, et un langage de prog, c’est comme un organisme vivant : pour répondre aux nouveaux défis, il doit évoluer.

Avec les nouvelles versions de C#, les interfaces ont appris de nouveaux tours. Un des plus visibles — les membres statiques dans les interfaces. Maintenant, les interfaces peuvent contenir des méthodes statiques, des propriétés et des events statiques. Dans les nouvelles versions de C# (à partir de C# 11), tu peux même déclarer des méthodes statiques abstraites, qui doivent être implémentées par les types qui réalisent cette interface.

C’est un gros changement de paradigme, qui modifie la façon de faire du code générique et orienté objet.

Pour faire simple : un membre statique d’interface, c’est un membre "commun", accessible via le type de l’interface lui-même (ou via le type qui l’implémente), pas via une instance d’objet.

Jusqu’à récemment, seuls les classes, structs et enums pouvaient avoir des méthodes et propriétés statiques, mais maintenant les interfaces aussi ont ce super-pouvoir.

À quoi ça ressemble ? Exemple de syntaxe


public interface IMyMath
{
    static int Add(int a, int b) => a + b; // Méthode statique (implémentation par défaut)

    static abstract int Multiply(int a, int b); // Doit être implémentée par le type qui réalise l’interface 
}
  • static — membre dispo au niveau du type, pas de l’instance.
  • static abstract — le contrat "exige" d’implémenter la méthode statique dans le type qui réalise l’interface.
  • Dans les interfaces (comme dans les classes), tu peux maintenant déclarer des méthodes, propriétés et events statiques. Tu peux aussi créer des constantes. Mais les interfaces ne peuvent toujours pas avoir de champs d’instance ou de champs statiques (sauf les constantes).

Le but des membres statiques dans les interfaces, c’est de pouvoir déclarer des "opérations" universelles. Par exemple, si t’as une collection d’objets et tu veux appeler "Comparer" dessus sans savoir quel type réalise l’interface, c’est possible avec les membres statiques abstraits.

2. Méthodes statiques avec implémentation dans l’interface

Pourquoi on en a besoin ?

Le problème classique : tu veux décrire non seulement des méthodes "d’instance" (genre faire un truc avec un objet), mais aussi des méthodes "statiques" (genre créer un nouvel objet à partir d’une string ou comparer deux objets de façon statique). Avant, fallait bricoler avec des patterns (Factory, Comparer, Helper), mais maintenant tu peux l’exprimer direct dans l’interface.

C’est devenu super important pour les Generics et les algos qui bossent avec n’importe quel type :

  • Implémenter des opérateurs universels (genre addition, comparaison).
  • Restreindre le code générique : "N’importe quel type qui a une méthode statique ou un opérateur…"
  • Sérialisation/désérialisation : quand tu dois créer un objet à partir d’une string sans connaître le type à l’écriture du code.

Méthodes statiques avec corps

Depuis C# 8, les interfaces peuvent avoir des méthodes statiques avec corps. C’est comme les méthodes statiques classiques dans une classe.


public interface IUtility
{
    static void PrintHello()
    {
        Console.WriteLine("Salut depuis l’interface !");
    }
}

Tu peux appeler cette méthode comme ça : IUtility.PrintHello();

C’est pratique pour les fonctions utilitaires qui logiquement appartiennent à l’interface, mais pas à une implémentation précise. Par exemple : stats sur tous les objets du type, méthodes factory (CreateDefault), vérifs communes (genre vérifier les valeurs valides).

Attention : les membres statiques d’interface ne sont pas "overridés" dans les classes

Si tu déclares dans l’interface static void Method() { ... }, la classe qui réalise l’interface peut déclarer une méthode statique du même nom et avec la même signature — mais ce n’est pas un override ! Ce sont juste deux méthodes indépendantes — le nom est le même, mais ce n’est pas une "méthode statique virtuelle".

3. Membres statiques abstraits

Depuis C# 11, tu peux déclarer dans les interfaces des méthodes static abstract. Ça veut dire : "chaque classe ou struct qui réalise cette interface doit déclarer un membre statique avec la même signature".

Exemple :


public interface IParsable<T>
{
    static abstract T Parse(string s);
}

Tout type qui réalise cette interface doit déclarer une méthode statique Parse(string s).

Implémentation de cette interface sur une classe


public class Temperature : IParsable<Temperature>
{
    public int Value { get; set; }

    // Implémentation statique !
    public static Temperature Parse(string s)
    {
        var temp = new Temperature();
        temp.Value = int.Parse(s);
        return temp;
    }
}

Comment ça marche ?

C’est surtout cool dans le code générique (Generics) :


public static T ParseFromString<T>(string s) where T : IParsable<T>
{
    return T.Parse(s);
}

// Utilisation :
var temp = ParseFromString<Temperature>("42");

Maintenant tu peux écrire du vrai code universel qui marche avec tous les types qui réalisent un comportement "statique" !

4. Membres statiques dans les interfaces vs. membres statiques classiques des classes

Caractéristique Membre statique de classe Membre statique d’interface
Hérité Non Non, mais implémenté dans le cadre du contrat d’interface
Implémentation obligatoire Non Seulement si static abstract
Utilisable dans les Generics Non (avant C# 11) Oui (avec static abstract)
Peut avoir une implémentation par défaut Oui Oui
Override Non Non, juste obligé d’implémenter
Visibilité à l’appel Via le nom du type Via le type de l’interface ou du type qui l’implémente

7. Exemples du monde réel

Voyons comment on peut améliorer notre petite appli d’apprentissage avec ces nouveautés.

Imaginons une interface "IPrintable" :


public interface IPrintable
{
    void Print();
    static void PrintAll(IEnumerable<IPrintable> items)
    {
        foreach (var item in items)
        {
            item.Print();
        }
    }
}

Maintenant tu peux appeler facilement :


var documents = new List<IPrintable>
{
    new Invoice { Number = "INV-001" },
    new Receipt { Number = "RC-007" }
};
IPrintable.PrintAll(documents); // méthode statique de l’interface !

Cette archi est parfaite pour les opérations "de groupe" sur toutes les implémentations de l’interface.

Un exemple plus avancé : addition générique de types numériques

Imaginons une interface :


public interface IAddable<T>
{
    static abstract T Add(T left, T right);
}

Implémentation pour les entiers (classe wrapper) :


public struct MyInt : IAddable<MyInt>
{
    public int Value { get; }
    public MyInt(int val) => Value = val;
    public static MyInt Add(MyInt left, MyInt right) => new MyInt(left.Value + right.Value);
}

Et enfin, une fonction universelle pour additionner deux nombres de type T :


public static T Sum<T>(T a, T b) where T : IAddable<T>
{
    return T.Add(a, b);
}

// Utilisation :
var x = new MyInt(5);
var y = new MyInt(6);
var z = Sum(x, y); // z.Value == 11

C’est pour ce genre d’universalité qu’on a ajouté les membres statiques dans les interfaces !

8. Erreurs classiques et subtilités

La vie avec les nouvelles features n’est pas toujours aussi simple que dans les exemples. Voilà quelques points qui peuvent faire galérer un débutant :

Les méthodes statiques d’interface ne sont pas "héritées" par la classe qui réalise l’interface. Si tu déclares dans l’interface static void Foo(), alors MyClass.Foo() et IMyInterface.Foo() — ce sont deux méthodes totalement différentes.

Static abstract doit absolument être implémenté. Si tu oublies — le compilateur va râler que la classe n’implémente pas complètement l’interface.

Contraintes génériques : pour utiliser les membres statiques abstraits, il faut restreindre le paramètre generic sur l’interface (where T : IMyInterface).

Tous les outils ne gèrent pas encore ces nouveautés. Par exemple, Rider, VS Code ou les vieux analyseurs Roslyn ne savent pas toujours bien afficher les membres static abstract dans les interfaces si la version .NET ne supporte pas C# 11+.

À ne pas confondre avec les méthodes d’extension d’interface : elles sont implémentées à part et ne marchent pas comme des membres statiques.

2
Mission
C# SELF, niveau 24, leçon 1
Bloqué
Création d'une méthode statique dans une interface
Création d'une méthode statique dans une interface
2
Mission
C# SELF, niveau 24, leçon 1
Bloqué
Méthode statique avec interface
Méthode statique avec interface
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION