Classe System.TypeInitializationException
Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.
Lorsqu'un initialiseur de classe ne réussit pas à initialiser un type, Lorsqu'un initialiseur de classe n'arrive pas à initialiser un type, une TypeInitializationException est créée et passe une référence à l'exception levée par l'initialiseur de classe du type. La propriété InnerException de TypeInitializationException contient l’exception sous-jacente.
En règle générale, l’exception TypeInitializationException reflète une condition catastrophique (le runtime ne peut pas instancier un type) qui empêche une application de continuer. Le plus souvent, l’exception TypeInitializationException est déclenchée en réponse à une modification de l’environnement en cours d’exécution de l’application. Par conséquent, sauf éventuellement pour la résolution des problèmes de code de débogage, l’exception ne doit pas être gérée dans un bloc try
/catch
. Au lieu de cela, la cause de l’exception doit être examinée et éliminée.
TypeInitializationException utilise le HRESULT COR_E_TYPEINITIALIZATION
, qui a la valeur 0x80131534.
Pour obtenir la liste des valeurs initiales des propriétés d’une instance de TypeInitializationException, consultez le TypeInitializationException constructeurs.
Les sections suivantes décrivent certaines des situations dans lesquelles une exception TypeInitializationException est levée.
Constructeurs statiques
Un constructeur statique, s’il en existe un, est appelé automatiquement par le runtime avant de créer une nouvelle instance d’un type. Les constructeurs statiques peuvent être définis explicitement par un développeur. Si un constructeur statique n’est pas défini explicitement, les compilateurs en créent automatiquement un pour initialiser les membres static
(en C# ou F#) ou Shared
(en Visual Basic) du type. Pour plus d’informations sur les constructeurs statiques, consultez Constructeurs statiques.
La plupart du temps, une exception TypeInitializationException est déclenchée lorsqu’un constructeur statique ne peut pas instancier un type. La propriété InnerException indique pourquoi le constructeur statique n’a pas pu instancier le type. Voici quelques-unes des causes les plus courantes d’une exception TypeInitializationException :
Exception non prise en charge dans un constructeur statique
Si une exception est déclenchée dans un constructeur statique, cette exception est encapsulée dans une exception TypeInitializationException et le type ne peut pas être instancié.
Ce qui rend souvent cette exception difficile à résoudre est que les constructeurs statiques ne sont pas toujours définis explicitement dans le code source. Un constructeur statique existe dans un type si :
Elle a été explicitement définie en tant que membre d’un type.
Le type a des variables
static
(en C# ou F#) ouShared
(en Visual Basic) qui sont déclarées et initialisées dans une seule instruction. Dans ce cas, le compilateur de langage génère un constructeur statique pour le type. Vous pouvez l’inspecter à l’aide d’un utilitaire tel que IL Disassembler. Par exemple, lorsque les compilateurs C# et VB compilent l’exemple suivant, ils génèrent le code IL pour un constructeur statique similaire à ceci :
.method private specialname rtspecialname static void .cctor() cil managed { // Code size 12 (0xc) .maxstack 8 IL_0000: ldc.i4.3 IL_0001: newobj instance void TestClass::.ctor(int32) IL_0006: stsfld class TestClass Example::test IL_000b: ret } // end of method Example::.cctor
L’exemple suivant montre une exception TypeInitializationException déclenchée par un constructeur statique généré par le compilateur. La classe
Example
inclut un champstatic
(en C#) ouShared
(en Visual Basic) de typeTestClass
instancié en passant une valeur de 3 à son constructeur de classe. Toutefois, cette valeur est illégale ; seules les valeurs de 0 ou 1 sont autorisées. Par conséquent, le constructeur de classeTestClass
lève une ArgumentOutOfRangeException. Étant donné que cette exception n’est pas gérée, elle est encapsulée dans une exception TypeInitializationException.using System; public class Example { private static TestClass test = new TestClass(3); public static void Main() { Example ex = new Example(); Console.WriteLine(test.Value); } } public class TestClass { public readonly int Value; public TestClass(int value) { if (value < 0 || value > 1) throw new ArgumentOutOfRangeException(nameof(value)); Value = value; } } // The example displays the following output: // Unhandled Exception: System.TypeInitializationException: // The type initializer for 'Example' threw an exception. ---> // System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. // at TestClass..ctor(Int32 value) // at Example..cctor() // --- End of inner exception stack trace --- // at Example.Main()
Public Class Example1 Shared test As New TestClass(3) Public Shared Sub Main() Dim ex As New Example1() Console.WriteLine(test.Value) End Sub End Class Public Class TestClass Public ReadOnly Value As Integer Public Sub New(value As Integer) If value < 0 Or value > 1 Then Throw New ArgumentOutOfRangeException(NameOf(value)) value = value End Sub End Class ' The example displays the following output: ' Unhandled Exception: System.TypeInitializationException: ' The type initializer for 'Example' threw an exception. ---> ' System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. ' at TestClass..ctor(Int32 value) ' at Example..cctor() ' --- End of inner exception stack trace --- ' at Example.Main()
Notez que le message d’exception affiche des informations sur la propriété InnerException.
Un assembly ou un fichier de données manquant
Une cause courante d’une exception TypeInitializationException est qu’un assembly ou un fichier de données qui était présent dans les environnements de développement et de test d’une application est absent de son environnement d’exécution. Par exemple, vous pouvez compiler l’exemple suivant dans un assembly nommé Missing1a.dll à l’aide de cette syntaxe de ligne de commande :
csc -t:library Missing1a.cs
fsc --target:library Missing1a.fs
vbc Missing1a.vb -t:library
using System; public class InfoModule { private DateTime firstUse; private int ctr = 0; public InfoModule(DateTime dat) { firstUse = dat; } public int Increment() { return ++ctr; } public DateTime GetInitializationTime() { return firstUse; } }
open System type InfoModule(firstUse: DateTime) = let mutable ctr = 0 member _.Increment() = ctr <- ctr + 1 ctr member _.GetInitializationTime() = firstUse
Public Class InfoModule Private firstUse As DateTime Private ctr As Integer = 0 Public Sub New(dat As DateTime) firstUse = dat End Sub Public Function Increment() As Integer ctr += 1 Return ctr End Function Public Function GetInitializationTime() As DateTime Return firstUse End Function End Class
Vous pouvez ensuite compiler l’exemple suivant sur un exécutable nommé Missing1.exe en incluant une référence à Missing1a.dll :
csc Missing1.cs /r:Missing1a.dll
vbc Missing1.vb /r:Missing1a.dll
Toutefois, si vous renommez, déplacez ou supprimez Missing1a.dll et exécutez l’exemple, il lève une exception TypeInitializationException et affiche la sortie illustrée dans l’exemple. Notez que le message d’exception affiche des informations sur la propriété InnerException. Dans ce cas, l’exception interne est une FileNotFoundException qui est déclenchée, car le runtime ne trouve pas l’assembly dépendant.
using System; public class MissingEx1 { public static void Main() { Person p = new Person("John", "Doe"); Console.WriteLine(p); } } public class Person { static readonly InfoModule s_infoModule; readonly string _fName; readonly string _lName; static Person() { s_infoModule = new InfoModule(DateTime.UtcNow); } public Person(string fName, string lName) { _fName = fName; _lName = lName; s_infoModule.Increment(); } public override string ToString() { return string.Format("{0} {1}", _fName, _lName); } } // The example displays the following output if missing1a.dll is renamed or removed: // Unhandled Exception: System.TypeInitializationException: // The type initializer for 'Person' threw an exception. ---> // System.IO.FileNotFoundException: Could not load file or assembly // 'Missing1a, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' // or one of its dependencies. The system cannot find the file specified. // at Person..cctor() // --- End of inner exception stack trace --- // at Person..ctor(String fName, String lName) // at Example.Main()
open System type Person(fName, lName) = static let infoModule = InfoModule DateTime.UtcNow do infoModule.Increment() |> ignore override _.ToString() = $"{fName} {lName}" let p = Person("John", "Doe") printfn $"{p}" // The example displays the following output if missing1a.dll is renamed or removed: // Unhandled Exception: System.TypeInitializationException: // The type initializer for 'Person' threw an exception. ---> // System.IO.FileNotFoundException: Could not load file or assembly // 'Missing1a, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' // or one of its dependencies. The system cannot find the file specified. // at Person..cctor() // --- End of inner exception stack trace --- // at Person..ctor(String fName, String lName) // at Example.Main()
Module Example3 Public Sub Main() Dim p As New Person("John", "Doe") Console.WriteLine(p) End Sub End Module Public Class Person Shared infoModule As InfoModule Dim fName As String Dim mName As String Dim lName As String Shared Sub New() infoModule = New InfoModule(DateTime.UtcNow) End Sub Public Sub New(fName As String, lName As String) Me.fName = fName Me.lName = lName infoModule.Increment() End Sub Public Overrides Function ToString() As String Return String.Format("{0} {1}", fName, lName) End Function End Class ' The example displays the following output if missing1a.dll is renamed or removed: ' Unhandled Exception: System.TypeInitializationException: ' The type initializer for 'Person' threw an exception. ---> ' System.IO.FileNotFoundException: Could not load file or assembly ' 'Missing1a, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' ' or one of its dependencies. The system cannot find the file specified. ' at Person..cctor() ' --- End of inner exception stack trace --- ' at Person..ctor(String fName, String lName) ' at Example.Main()
Remarque
Dans cet exemple, une exception TypeInitializationException a été levée, car un assembly n’a pas pu être chargé. L’exception peut également être levée si un constructeur statique tente d’ouvrir un fichier de données, tel qu’un fichier de configuration, un fichier XML ou un fichier contenant des données sérialisées, qu’il ne peut pas trouver.
Valeurs de délai d’expiration de correspondance d’expression régulière
Vous pouvez définir la valeur de délai d’expiration par défaut pour une opération de correspondance de modèle d’expression régulière par domaine d’application. Le délai d’expiration est défini par une valeur TimeSpan pour la propriété « REGEX_DEFAULT_MATCH_TIMEOUT » à la méthode AppDomain.SetData. L’intervalle de temps doit être un objet TimeSpan valide supérieur à zéro et inférieur à environ 24 jours. Si ces exigences ne sont pas remplies, la tentative de définition de la valeur de délai d’expiration par défaut déclenche un ArgumentOutOfRangeException, qui à son tour est encapsulé dans une exception TypeInitializationException.
L’exemple suivant montre l'exception TypeInitializationException déclenchée lorsque la valeur affectée à la propriété « REGEX_DEFAULT_MATCH_TIMEOUT » n’est pas valide. Pour éliminer l’exception, définissez la propriété « REGEX_DEFAULT_MATCH_TIMEOUT » sur une valeur TimeSpan supérieure à zéro et inférieure à environ 24 jours.
using System;
using System.Text.RegularExpressions;
public class RegexEx1
{
public static void Main()
{
AppDomain domain = AppDomain.CurrentDomain;
// Set a timeout interval of -2 seconds.
domain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds(-2));
Regex rgx = new Regex("[aeiouy]");
Console.WriteLine("Regular expression pattern: {0}", rgx.ToString());
Console.WriteLine("Timeout interval for this regex: {0} seconds",
rgx.MatchTimeout.TotalSeconds);
}
}
// The example displays the following output:
// Unhandled Exception: System.TypeInitializationException:
// The type initializer for 'System.Text.RegularExpressions.Regex' threw an exception. --->
// System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
// Parameter name: AppDomain data 'REGEX_DEFAULT_MATCH_TIMEOUT' contains an invalid value or
// object for specifying a default matching timeout for System.Text.RegularExpressions.Regex.
// at System.Text.RegularExpressions.Regex.InitDefaultMatchTimeout()
// at System.Text.RegularExpressions.Regex..cctor()
// --- End of inner exception stack trace ---
// at System.Text.RegularExpressions.Regex..ctor(String pattern)
// at Example.Main()
open System
open System.Text.RegularExpressions
let domain = AppDomain.CurrentDomain
// Set a timeout interval of -2 seconds.
domain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds -2)
let rgx = Regex "[aeiouy]"
printfn $"Regular expression pattern: {rgx}"
printfn $"Timeout interval for this regex: {rgx.MatchTimeout.TotalSeconds} seconds"
// The example displays the following output:
// Unhandled Exception: System.TypeInitializationException:
// The type initializer for 'System.Text.RegularExpressions.Regex' threw an exception. --->
// System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
// Parameter name: AppDomain data 'REGEX_DEFAULT_MATCH_TIMEOUT' contains an invalid value or
// object for specifying a default matching timeout for System.Text.RegularExpressions.Regex.
// at System.Text.RegularExpressions.Regex.InitDefaultMatchTimeout()
// at System.Text.RegularExpressions.Regex..cctor()
// --- End of inner exception stack trace ---
// at System.Text.RegularExpressions.Regex..ctor(String pattern)
// at Example.Main()
Imports System.Text.RegularExpressions
Module Example4
Public Sub Main()
Dim domain As AppDomain = AppDomain.CurrentDomain
' Set a timeout interval of -2 seconds.
domain.SetData("REGEX_DEFAULT_MATCH_TIMEOUT", TimeSpan.FromSeconds(-2))
Dim rgx As New Regex("[aeiouy]")
Console.WriteLine("Regular expression pattern: {0}", rgx.ToString())
Console.WriteLine("Timeout interval for this regex: {0} seconds",
rgx.MatchTimeout.TotalSeconds)
End Sub
End Module
' The example displays the following output:
' Unhandled Exception: System.TypeInitializationException:
' The type initializer for 'System.Text.RegularExpressions.Regex' threw an exception. --->
' System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
' Parameter name: AppDomain data 'REGEX_DEFAULT_MATCH_TIMEOUT' contains an invalid value or
' object for specifying a default matching timeout for System.Text.RegularExpressions.Regex.
' at System.Text.RegularExpressions.Regex.InitDefaultMatchTimeout()
' at System.Text.RegularExpressions.Regex..cctor()
' --- End of inner exception stack trace ---
' at System.Text.RegularExpressions.Regex..ctor(String pattern)
' at Example.Main()
Calendriers et données culturelles
Si vous tentez d’instancier un calendrier, mais que le runtime ne parvient pas à instancier l’objet CultureInfo qui correspond à ce calendrier, il lève une exception TypeInitializationException. Cette exception peut être levée par les constructeurs de classe de calendrier suivants :
- Le constructeur sans paramètre de la classe JapaneseCalendar.
- Le constructeur sans paramètre de la classe KoreanCalendar.
- Le constructeur sans paramètre de la classe TaiwanCalendar.
Étant donné que les données culturelles de ces cultures doivent être disponibles sur tous les systèmes, vous devriez rarement, voire jamais, rencontrer cette exception.