2010-05-29 7 views
41

Est-ce un constructeur statique sur une classe générique pour être exécuté tous les types que vous passez dans le paramètre générique tel que ceci:C# Constructor statique générique

class SomeGenericClass<T> 
{ 
     static List<T> _someList; 
     static SomeGenericClass() 
     { 
      _someList = new List<T>(); 
     } 
} 

Y a-t-il des dos de tirage à l'aide de cette approche?

Répondre

52

Oui, le constructeur statique sera appelé une fois pour chaque type de classe fermée (le type créé lorsque vous spécifiez les paramètres de type). Voir le C# 3 specification, §10.12 Constructeurs statiques.

Le constructeur statique pour un type de classe fermée s'exécute au plus une fois dans un domaine d'application donné.

et aussi:

Parce que le constructeur statique est exécuté une seule fois pour chaque fermé conçu pour le type de classe, il est un endroit pratique pour appliquer des contrôles en temps d'exécution sur le paramètre de type qui ne peut pas être vérifiée à compiler-time via des contraintes (§10.1.5). Par exemple, le type suivant utilise un constructeur statique pour faire respecter que l'argument de type est un ENUM:

class Gen<T> where T: struct 
{ 
    static Gen() { 
     if (!typeof(T).IsEnum) { 
      throw new ArgumentException("T must be an enum"); 
     } 
    } 
} 

Il est également pertinent de lire §4.4.2 ouvert et fermé types:

Au moment de l'exécution, tout le code dans une déclaration de type générique est exécuté dans le contexte d'un type construit fermé qui a été créé en appliquant des arguments de type à la déclaration générique. Chaque paramètre de type dans le type générique est lié à un type d'exécution particulier. Le traitement d'exécution de toutes les instructions et expressions se produit toujours avec des types fermés et les types ouverts se produisent uniquement lors du traitement de la compilation.

Chaque type construit fermé possède son propre ensemble de variables statiques, qui ne sont pas partagées avec d'autres types construits fermés.

Ce programme que vous pouvez vous lancer démontre que le constructeur statique est appelé trois fois, et pas seulement une fois:

public class Program 
{ 
    class SomeGenericClass<T> 
    { 
     static SomeGenericClass() 
     { 
      Console.WriteLine(typeof(T)); 
     } 
    } 

    class Baz { } 

    static void Main(string[] args) 
    { 
     SomeGenericClass<int> foo = new SomeGenericClass<int>(); 
     SomeGenericClass<string> bar = new SomeGenericClass<string>(); 
     SomeGenericClass<Baz> baz = new SomeGenericClass<Baz>(); 
    } 
} 

Sortie:

 
System.Int32 
System.String 
Program+Baz 
+0

Comment est-ce une classe statique? –

+5

@Jouke van der Maas, qui a parlé d'une classe statique? La question concerne le constructeur statique d'une classe générique, pas une classe statique ... –

+0

Ce n'était ni l'un ni l'autre, donc ça s'applique toujours :) –

0

Oui, les membres statiques et les constructeurs de types génériques sont spécifiques à un paramètre générique et seront exécutés pour chaque type différent. Il n'y a pas de vrais inconvénients. Soyez prudent lorsque vous refactorisez une classe non générique en une classe générique.

0

Oui, il fonctionnera pour chaque type que vous fournissez car pour chaque type fourni, vous obtenez un type séparé.

2

Il fonctionnera, mais une nouvelle 'instance' sera créé pour chaque type que vous utilisez.