Classes statiques et membres de classe statique (Guide de programmation C#)

Une classe statique est fondamentalement identique à une classe non statique, à une différence près : une classe statique ne peut pas être instanciée. En d’autres termes, vous ne pouvez pas utiliser l’opérateur new pour créer une variable du type classe. Étant donné qu’il n’y a aucune variable d’instance, vous accédez aux membres d’une classe statique en utilisant le nom de classe lui-même. Par exemple, si vous avez une classe statique nommée UtilityClass qui a une méthode statique publique nommée MethodA, vous appelez la méthode comme illustré dans l’exemple suivant :

UtilityClass.MethodA();  

Une classe statique peut servir de conteneur pratique pour des ensembles de méthodes qui opèrent simplement sur des paramètres d’entrée et n’ont pas à obtenir ou définir de champs d’instance internes. Par exemple, dans la bibliothèque de classes .NET, la classe statique System.Math contient des méthodes qui effectuent des opérations mathématiques, sans aucune exigence de stocker ou de récupérer des données uniques à une instance particulière de la Math classe. Autrement dit, vous appliquez les membres de la classe en spécifiant le nom de la classe et le nom de la méthode, comme illustré dans l’exemple suivant.

double dub = -3.14;  
Console.WriteLine(Math.Abs(dub));  
Console.WriteLine(Math.Floor(dub));  
Console.WriteLine(Math.Round(Math.Abs(dub)));  
  
// Output:  
// 3.14  
// -4  
// 3  

Comme dans le cas de tous les types de classes, les informations de type d’une classe statique sont chargées par le runtime .NET lorsque le programme qui référence la classe est chargé. Le programme ne peut pas spécifier exactement quand la classe est chargée. Toutefois, il est garanti qu’elle sera chargée, que ses champs seront initialisés et que son constructeur statique sera appelé avant que la classe soit référencée pour la première fois dans votre programme. Un constructeur statique est appelé une seule fois et une classe statique reste en mémoire pendant la durée de vie du domaine d’application dans lequel votre programme réside.

Notes

Pour créer une classe non statique permettant la création d’une seule instance d’elle-même, consultez Implémentation d’un singleton en C#.

La liste suivante fournit les fonctionnalités principales d’une classe statique :

  • Elle contient uniquement des membres statiques.

  • Elle ne peut pas être instanciée.

  • Elle est verrouillée (sealed).

  • Elle ne peut pas contenir de constructeurs d’instances.

La création d’une classe statique est par conséquent très semblable à la création d’une classe contenant uniquement des membres statiques et un constructeur privé. Un constructeur privé empêche la classe d’être instanciée. L’avantage de l’utilisation d’une classe statique est que le compilateur peut vérifier qu’aucun membre d’instance n’a été ajouté par erreur. Le compilateur garantit que les instances de cette classe ne peuvent pas être créées.

Les classes statiques sont scellées (sealed) et ne peuvent par conséquent pas être héritées. Elles ne peuvent hériter d’aucune classe à part Object. Les classes statiques ne peuvent pas contenir de constructeur d’instance. Toutefois, ils peuvent contenir un constructeur statique. Les classes non statiques doivent également définir un constructeur statique si la classe contient des membres statiques qui requièrent une initialisation non triviale. Pour plus d’informations, consultez Constructeurs statiques.

Exemple

Voici un exemple d’une classe statique qui contient deux méthodes qui convertissent la température des degrés Celsius en degrés Fahrenheit et des degrés Fahrenheit en degrés Celsius :

public static class TemperatureConverter
{
    public static double CelsiusToFahrenheit(string temperatureCelsius)
    {
        // Convert argument to double for calculations.
        double celsius = Double.Parse(temperatureCelsius);

        // Convert Celsius to Fahrenheit.
        double fahrenheit = (celsius * 9 / 5) + 32;

        return fahrenheit;
    }

    public static double FahrenheitToCelsius(string temperatureFahrenheit)
    {
        // Convert argument to double for calculations.
        double fahrenheit = Double.Parse(temperatureFahrenheit);

        // Convert Fahrenheit to Celsius.
        double celsius = (fahrenheit - 32) * 5 / 9;

        return celsius;
    }
}

class TestTemperatureConverter
{
    static void Main()
    {
        Console.WriteLine("Please select the convertor direction");
        Console.WriteLine("1. From Celsius to Fahrenheit.");
        Console.WriteLine("2. From Fahrenheit to Celsius.");
        Console.Write(":");

        string? selection = Console.ReadLine();
        double F, C = 0;

        switch (selection)
        {
            case "1":
                Console.Write("Please enter the Celsius temperature: ");
                F = TemperatureConverter.CelsiusToFahrenheit(Console.ReadLine() ?? "0");
                Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
                break;

            case "2":
                Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(Console.ReadLine() ?? "0");
                Console.WriteLine("Temperature in Celsius: {0:F2}", C);
                break;

            default:
                Console.WriteLine("Please select a convertor.");
                break;
        }

        // Keep the console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Example Output:
    Please select the convertor direction
    1. From Celsius to Fahrenheit.
    2. From Fahrenheit to Celsius.
    :2
    Please enter the Fahrenheit temperature: 20
    Temperature in Celsius: -6.67
    Press any key to exit.
 */

Membres static

Une classe non statique peut contenir des méthodes, des champs, des propriétés ou des événements statiques. Le membre statique peut être appelé sur une classe même quand aucune instance de la classe n’a été créée. Le membre statique est toujours accessible par le nom de la classe, et non par le nom de l’instance. Une seule copie d’un membre statique existe, quel que soit le nombre d’instances de la classe qui ont été créées. Les méthodes statiques et les propriétés ne peuvent pas accéder aux champs et événements non statiques de leur type contenant, et ils ne peuvent pas accéder à une variable d’instance d’un objet, sauf si elle est transmise explicitement dans un paramètre de méthode.

Il est plus courant de déclarer une classe non statique avec certains membres statiques que de déclarer une classe entière comme statique. Deux utilisations courantes des champs statiques consistent à conserver un décompte du nombre d’objets qui ont été instanciés ou à stocker une valeur qui doit être partagée entre toutes les instances.

Les méthodes statiques peuvent être surchargées mais pas substituées, car elles appartiennent à la classe et non pas à une instance de la classe.

Bien qu’un champ ne puisse pas être déclaré en tant que static const, un champ const est essentiellement statique dans son comportement. Il appartient au type, pas aux instances du type. Par conséquent, const les champs sont accessibles à l’aide de la même ClassName.MemberName notation que celle utilisée pour les champs statiques. Aucune instance d’objet n’est requise.

C# ne prend pas en charge les variables locales statiques (autrement dit, les variables déclarées dans l’étendue de méthode).

Vous déclarez des membres de classe statique en utilisant le mot clé static avant le type de retour du membre, comme illustré dans l’exemple suivant :

public class Automobile
{
    public static int NumberOfWheels = 4;

    public static int SizeOfGasTank
    {
        get
        {
            return 15;
        }
    }

    public static void Drive() { }

    public static event EventType? RunOutOfGas;

    // Other non-static fields and properties...
}

Les membres statiques sont initialisés avant le premier accès au membre statique et avant que le constructeur statique, s’il en existe un, soit appelé. Pour accéder à un membre de classe statique, utilisez le nom de la classe au lieu d’un nom de variable pour spécifier l’emplacement du membre, comme illustré dans l’exemple suivant :

Automobile.Drive();
int i = Automobile.NumberOfWheels;

Si votre classe contient des champs statiques, fournissez un constructeur statique qui les initialise quand la classe est chargée.

Un appel à une méthode statique génère une instruction d’appel dans le langage MSIL (Microsoft Intermediate Language), tandis qu’un appel à une méthode d’instance génère une callvirt instruction, qui vérifie également les références d’objet Null. Toutefois, la plupart du temps, l’écart de performances entre les deux n’est pas significatif.

Spécification du langage C#

Pour plus d’informations, consultez classes statiques, membres statiqueset constructeursstatiques dans la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.

Voir aussi