System.TypeInitializationException 類別
本文提供此 API 參考文件的補充備註。
當類別初始設定式無法初始化型別時,TypeInitializationException 便會建立並傳遞參考至型別之類別初始設定式所擲回的例外狀況。 InnerException的 TypeInitializationException 屬性會保存基礎例外狀況。
一般而言, TypeInitializationException 例外狀況會反映嚴重狀況(運行時間無法具現化類型),以防止應用程式繼續。 最常見的情況是, TypeInitializationException 會擲回 ,以回應應用程式執行環境中的一些變更。 因此,除了可能針對偵錯程式代碼進行疑難解答之外,不應該在 區塊中處理例外狀況 try
/catch
。 相反地,應該調查並排除例外狀況的原因。
TypeInitializationException 會使用具有 值0x80131534的 HRESULT COR_E_TYPEINITIALIZATION
。
如需執行個體的初始屬性值的清單TypeInitializationException,請參閱TypeInitializationException建構函式。
下列各節說明擲回例外狀況的一 TypeInitializationException 些情況。
靜態建構函式
如果存在靜態建構函式,則會由運行時間自動呼叫,再建立型別的新實例。 靜態建構函式可由開發人員明確定義。 如果未明確定義靜態建構函式,編譯程式會自動建立一個來初始化類型的任何 static
(在 C# 或 F# 中) 或 Shared
(在 Visual Basic 中) 成員。 如需靜態建構函式的詳細資訊,請參閱 靜態建構函式。
最常見的是, TypeInitializationException 當靜態建構函式無法具現化類型時,就會擲回例外狀況。 屬性 InnerException 指出靜態建構函式為何無法具現化類型。 例外狀況的一 TypeInitializationException 些較常見原因如下:
靜態建構函式中未處理的例外狀況
如果在靜態建構函式中擲回例外狀況,該例外狀況會包裝在例外狀況中 TypeInitializationException ,而且無法具現化類型。
通常使這個例外狀況難以疑難解答的是,靜態建構函式不一定會在原始程式碼中明確定義。 如果下列狀況,靜態建構函式存在於類型中:
它已明確定義為型別的成員。
此類型具有
static
在單一語句中宣告和初始化的 (在 C# 或 F# 中) 或Shared
(在 Visual Basic 中) 變數。 在此情況下,語言編譯程式會產生類型的靜態建構函式。 您可以使用 IL 反組譯程式等公用程式來檢查它。 例如,當 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 的值所定義。 時間間隔必須是大於零且小於大約 24 天的有效 TimeSpan 物件。 如果不符合這些需求,則嘗試設定預設逾時值會 ArgumentOutOfRangeException擲回 ,而這個值接著會包裝在例外狀況 TypeInitializationException 中。
下列範例顯示 TypeInitializationException 當指派給 「REGEX_DEFAULT_MATCH_TIMEOUT」 屬性的值無效時,所擲回的 。 若要排除例外狀況,請將 「REGEX_DEFAULT_MATCH_TIMEOUT」 屬性設定為 TimeSpan 大於零且小於大約 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: {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()
行事曆和文化數據
如果您嘗試具現化行事曆,但運行時間無法具現 CultureInfo 化對應至該行事歷的物件,則會擲回 TypeInitializationException 例外狀況。 下列行事曆類別建構函式可以擲回此例外狀況:
- 類別的 JapaneseCalendar 無參數建構函式。
- 類別的 KoreanCalendar 無參數建構函式。
- 類別的 TaiwanCalendar 無參數建構函式。
由於這些文化特性的文化特性數據應該可在所有系統上使用,因此您很少會遇到此例外狀況。