web-dev-qa-db-fra.com

Quand appelle-t-on un constructeur statique en C #?

Lorsque j'ai une classe contenant un constructeur statique, ce constructeur est-il appelé lorsque l'assembly contenant la classe est chargé pour la première fois ou lorsque la première référence à cette classe est touchée?

77
Jason

Lorsque la classe est accédée pour la première fois.

Constructeurs statiques (Guide de programmation C #)

Un constructeur statique est utilisé pour initialiser des données statiques ou pour effectuer une action particulière qui doit être effectuée une seule fois. Il est appelé automatiquement avant la création de la première instance ou la référence à des membres statiques.

83
user151323

Ce n'est pas aussi simple que l'on pourrait s'y attendre malgré une documentation simple. L'article de Jon Skeet http://csharpindepth.com/Articles/General/Beforefieldinit.aspx aborde cette question en détail. 

Résumé:

Le constructeur statique est garanti pour être exécuté immédiatement avant la première référence à un membre de cette classe - création d'instance ou propre méthode statique/propriété de classe.

Notez que les initilizateurs statiques (s'il n'y a pas de constructeur statique) garantissaient d'être exécutés à tout moment avant la première référence à un champ particulier.

35
Greg Beech

Le constructeur statique est appelé avant d’utiliser quoi que ce soit dans la classe, mais le moment précis où cela se produit dépend de la mise en œuvre.

Son appel est garanti avant le premier accès au membre statique et avant la création de la première instance. Si la classe n'est jamais utilisée, l'appel du constructeur statique n'est pas garanti.

19
Guffa

Si la méthode statique est appelée à partir de la classe parente, le constructeur statique ne sera pas appelé, même si cela est explicitement spécifié Voici un exemple. Le constructeur b n'est pas appelé si b.methoda () est appelé.

static void Main(string[] args)
{
    b.methoda();
}

class a
{
    public static void methoda()
    {
        //using initialized method data
    }
}

class b : a
{
    static b()
    {
        //some initialization
    }
}    
1
Andrew

Il semble exister un casse-tête avec des constructeurs statiques auquel on répond ailleurs, mais qui a mis du temps à se résumer en une explication simple. Tous les documents et toutes les explications affirment que le constructeur/intializer statique est "garanti" pour s'exécuter avant l'instanciation de la première classe ou la référence du premier champ statique. Le piège intervient lorsque vous essayez de mettre un singleton statique dans la classe qui crée une instance de lui-même (poulet/œuf). Dans ce cas, le constructeur statique finit par être appelé après le constructeur d'instance - et dans notre cas, le constructeur d'instance contenait du code reposant sur des données statiques.

Constructeur statique appelé après constructeur d'instance?

Le constructeur statique peut être exécuté après le constructeur non statique. Est-ce un bug du compilateur?

(la solution pour moi était de placer le singleton dans une classe séparée ou d'initialiser manuellement les données statiques dans le constructeur d'instance avant que cela ne soit requis) 

0
Etherman