System.TypeInitializationException-Klasse
Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.
Wenn die Initialisierung eines Typs durch eine Klasseninitialisierung fehlschlägt, wird eine TypeInitializationException erstellt. Dieser Ausnahme wird dann ein Verweis auf die Ausnahme übergeben, die durch die Klasseninitialisierung des Typs ausgelöst wurde. Die InnerException-Eigenschaft von TypeInitializationException enthält die zugrunde liegende Ausnahme.
In der Regel steht die TypeInitializationException-Ausnahme für einen katastrophalen Zustand (die Runtime kann keinen Typ instanziieren), der die weitere Ausführung einer Anwendung verhindert. In den meisten Fällen wird TypeInitializationException als Reaktion auf Änderungen in der Ausführungsumgebung der Anwendung ausgelöst. Abgesehen von der Problembehandlung zum Debuggen von Code sollte die Ausnahme daher nicht in einem try
/catch
-Block behandelt werden. Stattdessen sollte die Ursache der Ausnahme untersucht und beseitigt werden.
TypeInitializationException verwendet das HRESULT COR_E_TYPEINITIALIZATION
, das den Wert 0x80131534 aufweist.
Eine Liste der anfänglichen Eigenschaftswerte für eine Instanz von TypeInitializationException, finden Sie unter den TypeInitializationException Konstruktoren.
In den folgenden Abschnitten werden einige der Situationen beschrieben, in denen eine TypeInitializationException-Ausnahme ausgelöst wird.
Statische Konstruktoren
Sofern vorhanden, ruft die Runtime automatisch einen statischen Konstruktor auf, bevor eine neue Instanz eines Typs erstellt wird. Statische Konstruktoren können explizit von Entwickler*innen definiert werden. Wenn kein statischer Konstruktor explizit definiert ist, erstellen Compiler automatisch einen solchen Konstruktor, um beliebige static
-Member (in C# oder F#) oder Shared
-Member (in Visual Basic) des Typs zu initialisieren. Weitere Informationen zu statischen Konstruktoren finden Sie unter Statische Konstruktoren.
Eine TypeInitializationException-Ausnahme wird meist dann ausgelöst, wenn ein statischer Konstruktor nicht in der Lage ist, einen Typ zu instanziieren. Die InnerException-Eigenschaft gibt an, warum der statische Konstruktor den Typ nicht instanziieren konnte. Einige der häufigeren Ursachen einer TypeInitializationException-Ausnahme sind:
Eine unbehandelte Ausnahme in einem statischen Konstruktor
Wenn eine Ausnahme in einem statischen Konstruktor ausgelöst wird, wird diese Ausnahme in einer TypeInitializationException-Ausnahme umschlossen, und der Typ kann nicht instanziiert werden.
Häufig wird die Problembehandlung für diese Ausnahme dadurch erschwert, dass statische Konstruktoren nicht immer explizit im Quellcode definiert sind. Ein statischer Konstruktor ist in einem Typ vorhanden, wenn Folgendes gilt:
Er wurde explizit als Member eines Typs definiert.
Der Typ weist die Variablen
static
(in C# oder F#) oderShared
(in Visual Basic) auf, die in einer einzelnen Anweisung deklariert und initialisiert werden. In diesem Fall generiert der Sprachcompiler einen statischen Konstruktor für den Typ. Sie können den Konstruktor mit einem Hilfsprogramm wie IL Disassembler überprüfen. Wenn die C#- und VB-Compiler beispielsweise das folgende Beispiel kompilieren, generieren sie die IL (Intermediate Language, Zwischensprache) für einen statischen Konstruktor, die in etwa wie folgt aussieht:
.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
Das folgende Beispiel zeigt eine TypeInitializationException-Ausnahme, die von einem vom Compiler generierten statischen Konstruktor ausgelöst wird. Die
Example
-Klasse enthält ein Feldstatic
(in C#) oderShared
(in Visual Basic) vom TypTestClass
, das instanziiert wird, indem der Wert 3 an den Klassenkonstruktor übergeben wird. Dieser Wert ist jedoch ungültig. Es sind nur die Werte 0 oder 1 zulässig. Daher löst derTestClass
-Klassenkonstruktor eine ArgumentOutOfRangeException aus. Da diese Ausnahme nicht behandelt wird, wird sie in einer TypeInitializationException-Ausnahme umschlossen.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()
Beachten Sie, dass in der Ausnahmemeldung Informationen zur InnerException-Eigenschaft angezeigt werden.
Fehlende Assembly oder Datendatei
Eine häufige Ursache für eine TypeInitializationException-Ausnahme ist, dass eine Assembly oder Datendatei, die in den Entwicklungs- und Testumgebungen einer Anwendung vorhanden war, in der Laufzeitumgebung fehlt. Mit der folgenden Befehlszeilensyntax können Sie z. B. das folgende Beispiel für eine Assembly namens „Missing1a.dll“ kompilieren:
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
Anschließend können Sie das folgende Beispiel für eine ausführbare Datei namens „Missing1.exe“ kompilieren, indem Sie einen Verweis auf „Missing1a.dll“ einschließen:
csc Missing1.cs /r:Missing1a.dll
vbc Missing1.vb /r:Missing1a.dll
Wenn Sie „Missing1a.dll“ jedoch umbenennen, verschieben oder löschen und dann das Beispiel ausführen, wird eine TypeInitializationException-Ausnahme ausgelöst und die im Beispiel gezeigte Ausgabe angezeigt. Beachten Sie, dass die Ausnahmemeldung Informationen zur InnerException-Eigenschaft enthält. In diesem Fall ist die innere Ausnahme eine FileNotFoundException-Ausnahme, die ausgelöst wird, weil die Runtime die abhängige Assembly nicht finden kann.
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()
Hinweis
In diesem Beispiel wurde eine TypeInitializationException-Ausnahme ausgelöst, da eine Assembly nicht geladen werden konnte. Die Ausnahme kann auch ausgelöst werden, wenn ein statischer Konstruktor versucht, eine Datendatei zu öffnen, die er nicht findet (z. B. eine Konfigurationsdatei, eine XML-Datei oder eine Datei mit serialisierten Daten).
Timeoutwerte für den Abgleich regulärer Ausdrücke
Sie können den Standardtimeoutwert für den Musterabgleich mit regulären Ausdrücken pro Anwendungsdomäne festlegen. Das Timeout wird durch Festlegen eines TimeSpan-Werts für die REGEX_DEFAULT_MATCH_TIMEOUT-Eigenschaft für die AppDomain.SetData-Methode definiert. Das Zeitintervall muss ein gültiges TimeSpan-Objekt sein, das größer als Null und kleiner als etwa 24 Tage ist. Werden diese Anforderungen nicht erfüllt, löst der Versuch, den Standardtimeoutwert festzulegen, eine ArgumentOutOfRangeException aus, die wiederum in einer TypeInitializationException-Ausnahme umschlossen wird.
Das folgende Beispiel zeigt, dass die TypeInitializationException-Ausnahme ausgelöst wird, wenn der Wert, der der REGEX_DEFAULT_MATCH_TIMEOUT-Eigenschaft zugewiesen wird, ungültig ist. Um die Ausnahme zu beseitigen, legen Sie die REGEX_DEFAULT_MATCH_TIMEOUT-Eigenschaft auf einen TimeSpan-Wert fest, der größer als Null und kleiner als etwa 24 Tage ist.
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()
Kalender und Kulturdaten
Wenn Sie versuchen, einen Kalender zu instanziieren, die Runtime das CultureInfo-Objekt, das diesem Kalender entspricht, jedoch nicht instanziieren kann, wird eine TypeInitializationException-Ausnahme ausgelöst. Diese Ausnahme kann von den folgenden Kalenderklassenkonstruktoren ausgelöst werden:
- Parameterloser Konstruktor der JapaneseCalendar-Klasse
- Parameterloser Konstruktor der KoreanCalendar-Klasse
- Parameterloser Konstruktor der TaiwanCalendar-Klasse
Da die Kulturdaten für diese Kulturen auf allen Systemen verfügbar sein sollten, tritt diese Ausnahme wahrscheinlich nur selten oder gar nicht auf.