Menu

static en C# : classes, méthodes, champs et constructeurs statiques

Ce que signifie static en C# : des membres qui appartiennent au type plutôt qu'à un objet, un état partagé entre instances, les méthodes et classes statiques, les constructeurs statiques, const ou static readonly, using static, et l'erreur CS0120.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

static marque un membre qui appartient au type, pas à un objet. Un champ d'instance existe une fois par objet ; un champ statique existe une fois, un point c'est tout. Une méthode d'instance s'exécute sur un objet (order.Ship()) ; une méthode statique s'exécute sur le type (Math.Round(x)) et n'a besoin d'aucun objet.

Champs statiques : une seule copie, partagée

La façon la plus claire de voir la différence est un compteur. Chaque Order a son propre Id, mais le nombre de commandes créées jusque-là doit vivre dans un endroit partagé.

Sortie :

Ana #1, Ben #2, Chen #3
Orders created: 3

On accède aux membres statiques par le nom du type : Order.Created, et non a.Created. C# n'autorise pas l'accès à un membre statique via une instance (erreur CS0176), ce qui rend évident, à l'endroit de l'appel, que la valeur est partagée.

Méthodes statiques

Une méthode statique n'a pas de this. Elle travaille uniquement avec ses paramètres et avec d'autres membres statiques. C'est donc la forme naturelle des fonctions utilitaires qui calculent quelque chose à partir de leurs entrées :

Sortie :

61.38 EUR
7

Main lui-même est statique : le runtime l'appelle avant qu'aucun objet n'existe.

L'erreur CS0120 : du code statique qui utilise des membres d'instance

Comme Main est statique, les débutants rencontrent souvent cette erreur dès qu'ils ajoutent une seconde méthode :

class Program
{
    int visits;
    void Greet() { Console.WriteLine("Hello"); }

    static void Main()
    {
        Greet();    // error CS0120: An object reference is required for the non-static field, method, or property 'Program.Greet()'
        visits++;   // error CS0120: An object reference is required for the non-static field, method, or property 'Program.visits'
    }
}

Une méthode statique n'a pas d'objet, il n'y a donc aucun visits à incrémenter. Deux corrections, et la bonne dépend de la nature du membre :

  • Le membre est vraiment une donnée propre à chaque objet : créez un objet et utilisez-le. var app = new Program(); app.Greet();
  • Le membre n'a pas besoin d'état d'objet : marquez-le static. static void Greet() { ... }

Tout marquer static pour faire disparaître l'erreur fonctionne dans un tout petit programme et se transforme en état global dans un vrai. Décidez en vous demandant si la donnée appartient à un objet ou à tout le programme.

L'autre sens est toujours permis : les méthodes d'instance peuvent librement appeler des membres statiques.

Classes statiques

Une classe déclarée static ne peut contenir que des membres statiques et ne peut jamais être instanciée. C'est un groupe nommé de fonctions et de constantes.

Sortie :

77
100
True

Le compilateur fait respecter le contrat : un membre d'instance dans une classe statique donne l'erreur CS0708, et new sur elle l'erreur CS0712. Math, Console, File, Path et Enumerable sont toutes des classes statiques. Les méthodes d'extension doivent aussi vivre dans une classe statique.

Constructeurs statiques et static readonly

Un champ statique dont la valeur demande plus d'une expression peut être défini dans un constructeur statique, que le runtime exécute une fois, avant la première utilisation du type :

Sortie :

Before first use
ShippingRates initialized
5.50
3
2026-01-01

readonly signifie que le champ ne peut être affecté que dans son initialiseur ou dans le constructeur statique. Ensuite, il ne peut plus être réaffecté, même si l'objet vers lequel il pointe peut rester modifiable, c'est pourquoi le dictionnaire est exposé comme IReadOnlyDictionary.

const ou static readonly

Les deux vous donnent une valeur nommée partagée par tout le programme, et ils diffèrent par le moment où la valeur est fixée :

conststatic readonly
Valeur fixéeà la compilationà l'exécution, une fois
Types autorisésnombres, char, bool, string, enums, nulltout type
Implicitement statiqueoui (impossible d'écrire static const)déclaré statique explicitement
Copié dans les assemblies appelantsouinon, lu depuis le champ
Utilisable dans les cas de switch et les arguments d'attributouinon

La ligne sur la copie compte pour les bibliothèques : si l'assembly A déclare public const int MaxItems = 50; et que l'assembly B l'utilise, B contient le littéral 50. Passer A à 100 ne change rien pour B tant que B n'est pas recompilé. Pour les valeurs susceptibles de changer d'une version à l'autre, préférez static readonly.

using static

Une directive using static (C# 6) importe les membres statiques d'un type, pour pouvoir les appeler sans le nom du type :

Sortie :

Area: 28.27
40

Cela se lit bien dans du code très mathématique. Utilisez-la avec parcimonie ailleurs : un WriteLine ou un Parse seul cache le type d'où vient la méthode.

État statique et threads

Un champ statique est partagé par tous les threads du processus. L'incrémenter depuis plusieurs threads à la fois perd des mises à jour, car created++ est une lecture, une addition et une écriture, et deux threads peuvent les entrelacer. Utilisez Interlocked.Increment(ref created) pour les compteurs, ou un lock pour tout ce qui est plus gros. Les applications web sont l'endroit habituel où cela fait mal : chaque requête s'exécute sur un thread, donc un champ statique contenant « l'utilisateur courant » est partagé par tous les utilisateurs.

Une dernière subtilité : dans une classe générique, chaque type construit reçoit ses propres champs statiques. Cache<int>.Count et Cache<string>.Count sont deux champs différents.

Quand utiliser static

Bons usages :

  • Les fonctions pures qui calculent un résultat à partir de leurs arguments : formatage, conversions, validation.
  • Les constantes et les données de consultation en lecture seule partagées par le programme.
  • Les méthodes de fabrique, comme TimeSpan.FromMinutes(5) ou votre propre Temperature.FromCelsius(21).
  • Les méthodes d'extension.

Mauvais usages :

  • Un état global modifiable (l'utilisateur courant, un panier, des paramètres qui changent). Il couple chaque morceau de code qui y touche et rend les tests dépendants des restes laissés par les autres.
  • Tout ce que vous voudrez remplacer dans les tests, comme une horloge, une base de données ou un expéditeur d'e-mails. Les appels statiques ne peuvent pas être remplacés par une imitation ; une instance passée au constructeur le peut.

Questions fréquentes

Que signifie static en C# ?

Un membre static appartient au type lui-même plutôt qu'à un objet. Il existe une seule copie d'un champ statique, quel que soit le nombre d'objets, et une méthode statique s'appelle sur le nom du type (Math.Max(3, 7)) sans créer d'instance. Une méthode statique n'a pas de this, elle ne peut donc pas utiliser directement les champs d'instance.

Qu'est-ce qu'une classe statique en C# ?

Une classe déclarée static ne peut contenir que des membres statiques et ne peut jamais être instanciée (new sur elle donne l'erreur CS0712). Elle regroupe des fonctions apparentées qui n'ont besoin d'aucun état d'objet, comme Math, Console ou File. Les méthodes d'extension doivent être déclarées dans une classe statique.

Comment corriger « An object reference is required for the non-static field, method, or property » ?

C'est l'erreur CS0120 : une méthode statique, souvent Main, utilise un membre d'instance. Créez un objet et appelez le membre dessus (var app = new Program(); app.Run();), ou marquez le membre static s'il n'a pas besoin de données propres à chaque objet.

Quelle est la différence entre const et static readonly en C# ?

Un const est une constante de compilation (nombres, chaînes, bool, enums) dont la valeur est copiée dans chaque assembly qui l'utilise. Un champ static readonly est affecté une fois à l'exécution, dans son initialiseur ou dans le constructeur statique, et peut contenir n'importe quel type, comme un DateTime ou une liste. Utilisez const pour les valeurs qui ne changeront jamais, static readonly pour tout le reste.

Quand utiliser static en C# ?

Utilisez static pour du code qui ne travaille que sur ses paramètres (des fonctions pures comme un formateur de prix), pour des constantes et des caches vraiment globaux au programme, et pour les méthodes de fabrique. Évitez static pour tout ce qui garde un état propre à un utilisateur ou à une requête, ou que vous voudrez remplacer dans les tests : un état modifiable partagé est difficile à tester et dangereux entre threads sans verrou.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER