Oui, le constructeur statique sera appelée une fois pour chaque fermée type de classe (le type créé lorsque vous spécifiez le type des paramètres). Voir le C# 3 spécification, §10.12 constructeurs Statiques.
Le constructeur statique pour une fermeture de classe type s'exécute qu'une fois au plus dans un domaine d'application.
et aussi:
Parce que le constructeur statique est exécutée qu'une seule fois pour chaque construit fermé le type de classe, c'est un endroit commode à appliquer au moment de l'exécution des vérifications sur le type de paramètre qui ne peut pas être vérifié au moment de la compilation par les contraintes (§10.1.5). Par exemple, le type suivant utilise un constructeur statique pour faire valoir ce que de l'argument 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, le code à l'intérieur d'un type générique de la déclaration est effectuée dans le contexte d'un type construit fermé qui a été créé par l'application d'arguments de type pour le générique de la déclaration. Chaque paramètre de type dans le genre de type est lié à un particulier de type à l'exécution. Le moment de l'exécution du traitement de toutes les déclarations et les expressions se produit toujours fermés types, et d'ouvrir les types se produit uniquement lors de la compilation de traitement.
Chacun construit fermé de type a son propre ensemble de variables statiques, qui ne sont pas partagées avec d'autres types construits.
Ce programme que vous pouvez exécuter vous-même démontre que le constructeur statique est appelé trois fois, 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:
Système.Int32
Système.Chaîne
Programme+Baz