System.TypeInitializationException, klasa
Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.
Gdy inicjator klasy nie może zainicjować typu, TypeInitializationException element jest tworzony i przekazywany odwołanie do wyjątku zgłaszanego przez inicjator klasy typu. Właściwość InnerException zawiera TypeInitializationException wyjątek bazowy.
TypeInitializationException Zazwyczaj wyjątek odzwierciedla katastrofalny warunek (środowisko uruchomieniowe nie może utworzyć wystąpienia typu), który uniemożliwia kontynuowanie działania aplikacji. TypeInitializationException Najczęściej element jest zgłaszany w odpowiedzi na pewną zmianę w środowisku wykonywania aplikacji. W związku z tym, poza ewentualną możliwością rozwiązywania problemów z kodem debugowania, wyjątek nie powinien być obsługiwany w try
/catch
bloku. Zamiast tego należy zbadać i wyeliminować przyczynę wyjątku.
TypeInitializationException używa wartości HRESULT COR_E_TYPEINITIALIZATION
, która ma wartość 0x80131534.
Aby uzyskać listę początkowych wartości właściwości dla wystąpienia TypeInitializationExceptionprogramu , zobacz TypeInitializationException konstruktory.
W poniższych sekcjach opisano niektóre sytuacje, w których zgłaszany TypeInitializationException jest wyjątek.
Konstruktory statyczne
Konstruktor statyczny, jeśli istnieje, jest wywoływany automatycznie przez środowisko uruchomieniowe przed utworzeniem nowego wystąpienia typu. Konstruktory statyczne mogą być jawnie zdefiniowane przez dewelopera. Jeśli konstruktor statyczny nie jest jawnie zdefiniowany, kompilatory automatycznie tworzą jeden, aby zainicjować dowolne static
elementy członkowskie typu (w języku C# lub F#) lub Shared
(w Języku Visual Basic). Aby uzyskać więcej informacji na temat konstruktorów statycznych, zobacz Konstruktory statyczne.
Najczęściej zgłaszany TypeInitializationException jest wyjątek, gdy konstruktor statyczny nie może utworzyć wystąpienia typu. Właściwość InnerException wskazuje, dlaczego konstruktor statyczny nie mógł utworzyć wystąpienia typu. Oto niektóre z najczęstszych przyczyn wyjątku TypeInitializationException :
Nieobsługiwany wyjątek w konstruktorze statycznym
Jeśli wyjątek jest zgłaszany w konstruktorze statycznym, ten wyjątek jest opakowany w TypeInitializationException wyjątek i nie można utworzyć wystąpienia typu.
To, co często utrudnia rozwiązywanie problemów z tym wyjątkiem, jest to, że konstruktory statyczne nie zawsze są jawnie zdefiniowane w kodzie źródłowym. Konstruktor statyczny istnieje w typie, jeśli:
Został on jawnie zdefiniowany jako element członkowski typu.
Typ ma
static
zmienne (w języku C# lub F#) lubShared
(w Visual Basic), które są deklarowane i inicjowane w jednej instrukcji. W tym przypadku kompilator języka generuje konstruktor statyczny dla typu. Można go sprawdzić za pomocą narzędzia, takiego jak dezasembler IL. Na przykład gdy kompilatory języka C# i VB skompilują następujący przykład, generują il dla konstruktora statycznego, który jest podobny do następującego:
.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
W poniższym przykładzie pokazano TypeInitializationException wyjątek zgłoszony przez konstruktor statyczny wygenerowany przez kompilator. Klasa
Example
zawierastatic
pole typu (w języku C#) lubShared
(w Visual Basic),TestClass
które jest tworzone przez przekazanie wartości 3 do konstruktora klasy. Ta wartość jest jednak niedozwolona; dozwolone są tylko wartości 0 lub 1. W rezultacieTestClass
konstruktor klasy zgłasza błąd ArgumentOutOfRangeException. Ponieważ ten wyjątek nie jest obsługiwany, jest opakowany w TypeInitializationException wyjątek.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()
Zwróć uwagę, że komunikat o wyjątku InnerException wyświetla informacje o właściwości.
Brak zestawu lub pliku danych
Częstą przyczyną TypeInitializationException wyjątku jest to, że w środowisku uruchomieniowym brakuje zestawu lub pliku danych, który był obecny w środowiskach deweloperskich i testowych aplikacji. Na przykład można skompilować następujący przykład do zestawu o nazwie Missing1a.dll przy użyciu tej składni wiersza polecenia:
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
Następnie możesz skompilować następujący przykład do pliku wykonywalnego o nazwie Missing1.exe, dołączając odwołanie do Missing1a.dll:
csc Missing1.cs /r:Missing1a.dll
vbc Missing1.vb /r:Missing1a.dll
Jeśli jednak zmienisz nazwę, przeniesiesz lub usuniesz Missing1a.dll i uruchomisz przykład, zgłosi TypeInitializationException wyjątek i wyświetli dane wyjściowe pokazane w przykładzie. Należy pamiętać, że komunikat o wyjątku InnerException zawiera informacje o właściwości. W takim przypadku wyjątek wewnętrzny jest zgłaszany FileNotFoundException , ponieważ środowisko uruchomieniowe nie może odnaleźć zestawu zależnego.
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()
Uwaga
W tym przykładzie został zgłoszony wyjątek, TypeInitializationException ponieważ nie można załadować zestawu. Wyjątek można również zgłosić, jeśli konstruktor statyczny próbuje otworzyć plik danych, taki jak plik konfiguracji, plik XML lub plik zawierający dane serializowane, których nie można odnaleźć.
Wartości limitu czasu dopasowania wyrażenia regularnego
Możesz ustawić domyślną wartość limitu czasu dla operacji dopasowywania wzorca wyrażeń regularnych na podstawie domeny aplikacji. Limit czasu jest definiowany przez określenie TimeSpan wartości właściwości "REGEX_DEFAULT_MATCH_TIMEOUT" dla AppDomain.SetData metody . Przedział czasu musi być prawidłowym TimeSpan obiektem większym niż zero i krótszym niż około 24 dni. Jeśli te wymagania nie zostaną spełnione, próba ustawienia domyślnej wartości limitu czasu zgłasza ArgumentOutOfRangeExceptionwartość , która z kolei jest opakowana w TypeInitializationException wyjątek.
W poniższym przykładzie pokazano TypeInitializationException , że jest zgłaszany, gdy wartość przypisana do właściwości "REGEX_DEFAULT_MATCH_TIMEOUT" jest nieprawidłowa. Aby wyeliminować wyjątek, ustaw właściwość "REGEX_DEFAULT_MATCH_TIMEOUT" na TimeSpan wartość większą niż zero i mniejszą niż około 24 dni.
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()
Kalendarze i dane kulturowe
Jeśli próbujesz utworzyć wystąpienie kalendarza, ale środowisko uruchomieniowe nie może utworzyć wystąpienia obiektu odpowiadającego CultureInfo kalendarzowi, zgłasza wyjątek TypeInitializationException . Ten wyjątek może zostać zgłoszony przez następujące konstruktory klas kalendarza:
- Konstruktor bez parametrów JapaneseCalendar klasy.
- Konstruktor bez parametrów KoreanCalendar klasy.
- Konstruktor bez parametrów TaiwanCalendar klasy.
Ponieważ dane kulturowe tych kultur powinny być dostępne we wszystkich systemach, rzadko należy napotkać ten wyjątek.