System.TypeInitializationException 類別

本文提供此 API 參考文件的補充備註。

當類別初始設定式無法初始化型別時,TypeInitializationException 便會建立並傳遞參考至型別之類別初始設定式所擲回的例外狀況。 InnerExceptionTypeInitializationException 屬性會保存基礎例外狀況。

一般而言, 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 例外狀況。 下列行事曆類別建構函式可以擲回此例外狀況:

由於這些文化特性的文化特性數據應該可在所有系統上使用,因此您很少會遇到此例外狀況。