Codingly

Constructeurs statiques en C#

Posted in Posts by Romain Verdier on mai 12, 2008

On m’a posé une question il y a quelques temps :

« Et en C#, il y a l’équivalent des blocs static de Java ? »

La réponse est oui. En C# on peut définir des constructeurs statiques qui seront exécutés lors du premier des deux événements suivants :

  • Une instance du type est crée.
  • Un membre statique du type est accédé.

Le code suivant est un exemple, qui montre comment implémenter le pattern singleton en utilisant un tel constructeur :

public class Singleton
{
    private int useless;
    private static readonly Singleton instance;

    private Singleton()
    {
    }

    public static Singleton Instance
    {
        get { return instance; }
    }

    // Constructeur statique.
    static Singleton()
    {
        instance = new Singleton();
        instance.useless = instance.GetHashCode();
    }
}

La syntaxe est la même que pour un constructeur, sauf qu’il n’est plus nécessaire de définir le modificateur d’accès. Ces constructeurs sont utiles car ils permettent de réaliser des initialisations qui sont impossibles via les variable initializers. Néanmoins, si un type possède les deux, c’est le constructeur statique qui sera exécuté en dernier.

Petit QCM

Considérons les deux classes suivantes :

public class Brigitte
{
    public static string Name = Gustave.Name;    
    static Brigitte()
    {
        Name = "Brigitte";
    }

}

public class Gustave
{
    public static string Name = Brigitte.Name;
    static Gustave()
    {
        Name = "Gustave";
    }
}

Et le test unitaire suivant :

[Test]
public void BrigitteAndGustave()
{
    Assert.AreEqual("Brigitte", Brigitte.Name);
    Assert.AreEqual("Gustave", Gustave.Name);
}

Choisissez la réponse correcte :

  1. Le code ne compile pas.
  2. Le test ne passe pas à cause de la première assertion.
  3. Le test ne passe pas à cause de la seconde assertion.
  4. Le test ne passe pas car une StackOverFlowException est levée.
  5. Le test passe.
Tagged with: ,

4 Réponses

Subscribe to comments with RSS.

  1. grozeille said, on mai 12, 2008 at 8:18

    Il me semble que, tout comme pour les initialisations par défaut et les constructeurs, l’ordre d’affectation sera le suivant:
    public static string Name = XXX;
    puis
    static Brigitte(){ Name = YYY; }

    J’en déduis que Brigitte.Name vaudra « Brigitte ».
    Mais comme l’appelle au corps static de Brigitte provoque aussi celui de Gustave…
    Je n’en suis pas convaincu mais je dirais que le test passe (réponse 5, mais quelque chose me dit que c’est soit la réponse 2 ou 3…).

  2. Am Stupid (from Rodez) said, on mai 14, 2008 at 6:19

    Là comme ça je dirais 5 aussi… mais par contre je ne suis pas du tout sur du résultat des asserts…

  3. Jb Evain said, on mai 19, 2008 at 1:32

    «En C# on peut définir des constructeurs statiques qui seront exécutés lors du premier accès à un membre statique de la classe.»

    En fait ils sont exécutés la première fois que le JIT trouve n’importe quelle référence à la classe.

  4. Romain Verdier said, on mai 19, 2008 at 3:45

    Grozeille, Romain> Bravo, vous êtes de vrais petits compilateurs… Si vous voulez voir comment est gérée la dépendance circulaire, vous pouvez lancer une session de debug :’)

    Jb> Qu’entends-tu par n’importe quelle référence de la classe ?

    J’ai oublié de préciser qu’à l’instar des variable initializers statiques, la première instanciation d’un objet peut évidemment provoquer l’exécution du constructeur statique de son type si elle a lieu avant qu’un membre statique de ce type ne soit référencé.

    Est-ce à ça que tu fais allusion ?


Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s

%d blogueurs aiment cette page :