Класс System.TypeInitializationException
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Если инициализация типа инициализатором класса завершилась сбоем, то будет создан объект TypeInitializationException, которому будет передана ссылка на исключение, созданное инициализатором класса этого типа. Свойство InnerException TypeInitializationException содержит базовое исключение.
Как правило, TypeInitializationException исключение отражает катастрофическое условие (среда выполнения не может создать экземпляр типа), которое предотвращает продолжение приложения. Чаще всего TypeInitializationException вызывается в ответ на некоторые изменения в среде выполнения приложения. Следовательно, кроме возможного для устранения неполадок с кодом отладки, исключение не должно обрабатываться в блоке try
/catch
. Вместо этого следует исследовать и устранить причину исключения.
TypeInitializationException использует HRESULT COR_E_TYPEINITIALIZATION
, который имеет значение 0x80131534.
Список начальных значений свойств для экземпляра TypeInitializationException, см. в разделе TypeInitializationException конструкторы.
В следующих разделах описаны некоторые ситуации, в которых TypeInitializationException создается исключение.
Статические конструкторы
Статический конструктор, если он существует, вызывается автоматически средой выполнения перед созданием нового экземпляра типа. Статические конструкторы могут быть явно определены разработчиком. Если статический конструктор не определен явным образом, компиляторы автоматически создают его для инициализации любых static
(в C# или F#) или Shared
(в Visual Basic) элементов типа. Дополнительные сведения о статических конструкторах см. в разделе "Статические конструкторы".
Чаще всего создается исключение, TypeInitializationException если статический конструктор не может создать экземпляр типа. Свойство InnerException указывает, почему статический конструктор не смог создать экземпляр типа. Ниже приведены некоторые из наиболее распространенных TypeInitializationException причин исключения:
Необработанное исключение в статическом конструкторе
Если исключение создается в статическом конструкторе, это исключение упаковывается в TypeInitializationException исключение и не может быть создан экземпляр типа.
Что часто делает это исключение сложным для устранения неполадок, заключается в том, что статические конструкторы не всегда явно определены в исходном коде. Статический конструктор существует в типе, если:
Он был явно определен как член типа.
Тип имеет
static
переменные (в C# или F#) илиShared
(в Visual Basic), объявленные и инициализированные в одной инструкции. В этом случае компилятор языка создает статический конструктор для типа. Его можно проверить с помощью служебной программы, например IL Disassembler. Например, когда компиляторы C# и VB компилируют следующий пример, они создают IL для статического конструктора, аналогичного этому:
.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
В следующем примере показано исключение, созданное TypeInitializationException компилятором статического конструктора. Класс
Example
включаетstatic
поле типаTestClass
(в C#) илиShared
(в Visual Basic), которое создается путем передачи значения 3 в конструктор класса. Однако это значение является незаконным; Разрешены только значения 0 или 1. В результатеTestClass
конструктор класса создает исключение ArgumentOutOfRangeException. Так как это исключение не обрабатывается, он упаковывается в 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()
Обратите внимание, что сообщение об исключении отображает сведения о свойстве InnerException .
Отсутствует сборка или файл данных
Распространенной причиной TypeInitializationException исключения является отсутствие сборки или файла данных, присутствующих в средах разработки и тестирования приложения. Например, можно скомпилировать следующий пример в сборку с именем Missing1a.dll с помощью этого синтаксиса командной строки:
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
Затем можно скомпилировать следующий пример в исполняемый файл с именем Missing1.exe, включив ссылку на Missing1a.dll:
csc Missing1.cs /r:Missing1a.dll
vbc Missing1.vb /r:Missing1a.dll
Однако при переименовании, перемещении или удалении Missing1a.dll и выполнении примера он создает TypeInitializationException исключение и отображает выходные данные, показанные в примере. Обратите внимание, что сообщение об исключении содержит сведения о свойстве InnerException . В этом случае внутреннее исключение представляет собой FileNotFoundException исключение, которое возникает, так как среда выполнения не может найти зависимые сборки.
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()
Примечание.
В этом примере возникло TypeInitializationException исключение, так как не удалось загрузить сборку. Исключение также может быть вызвано, если статический конструктор пытается открыть файл данных, например файл конфигурации, XML-файл или файл, содержащий сериализованные данные, что он не может найти.
Значения времени ожидания регулярного выражения
Значение времени ожидания по умолчанию можно задать для операции сопоставления шаблонов регулярных выражений на основе домена для каждого приложения. Время ожидания определяется значением TimeSpan для свойства "REGEX_DEFAULT_MATCH_TIMEOUT" метода AppDomain.SetData . Интервал времени должен быть допустимым TimeSpan объектом, который больше нуля и меньше 24 дней. Если эти требования не выполнены, попытка задать значение времени ожидания по умолчанию вызывает исключение ArgumentOutOfRangeException, которое, в свою очередь, упаковывается в TypeInitializationException исключение.
В следующем примере показано TypeInitializationException , что возникает, когда значение, назначенное свойству "REGEX_DEFAULT_MATCH_TIMEOUT", недопустимо. Чтобы исключить исключение, задайте для свойства TimeSpan "REGEX_DEFAULT_MATCH_TIMEOUT" значение, которое больше нуля и меньше 24 дней.
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: {rgx.ToString()}");
Console.WriteLine($"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()
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()
Календари и культурные данные
Если вы пытаетесь создать экземпляр календаря, но среда выполнения не может создать экземпляр CultureInfo объекта, соответствующего тому календарю, он создает TypeInitializationException исключение. Это исключение можно создать следующими конструкторами классов календаря:
- Конструктор без JapaneseCalendar параметров класса.
- Конструктор без KoreanCalendar параметров класса.
- Конструктор без TaiwanCalendar параметров класса.
Так как культурные данные для этих региональных параметров должны быть доступны во всех системах, вы должны редко, если когда-либо, столкнуться с этим исключением.