Udostępnij za pomocą


klasa System.TypeInitializationException

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Gdy inicjalizator klasy nie może zainicjalizować typu, zostaje utworzony pewien obiekt TypeInitializationException i jest przekazywane odwołanie do wyjątku zgłoszonego przez inicjalizator klasy tego typu. Właściwość InnerException w TypeInitializationException zawiera wyjątek źródłowy.

Zazwyczaj wyjątek TypeInitializationException odzwierciedla katastrofalną sytuację (środowisko uruchomieniowe nie może utworzyć instancji typu), która uniemożliwia kontynuowanie działania aplikacji. Najczęściej TypeInitializationException jest zgłaszana w odpowiedzi na pewne zmiany 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 bloku try/catch. Zamiast tego należy zbadać i wyeliminować przyczynę wyjątku.

TypeInitializationException używa HRESULT COR_E_TYPEINITIALIZATION, który ma wartość 0x80131534.

Aby uzyskać listę początkowych wartości właściwości dla wystąpienia TypeInitializationException, zapoznaj się z konstruktorami TypeInitializationException.

W poniższych sekcjach opisano niektóre sytuacje, w których zgłaszany jest wyjątek TypeInitializationException.

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ć jakiekolwiek elementy oznaczone jako static (w językach C# lub F#) lub Shared (w Visual Basic) danego typu. Aby uzyskać więcej informacji na temat konstruktorów statycznych, zobacz Konstruktory statyczne.

Najczęściej wyjątek TypeInitializationException jest zgłaszany, gdy konstruktor statyczny nie może utworzyć wystąpienia typu. Właściwość InnerException wskazuje, dlaczego konstruktor statyczny nie mógł zainicjować 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 owinięty w wyjątku TypeInitializationException 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ło to jawnie zdefiniowane jako członek typu.

    • Typ ma zmienne static (w języku C# lub F#) lub Shared (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 przeanalizować za pomocą narzędzia, takiego jak Dezasembler IL. Na przykład gdy kompilatory języka C# i VB skompilują ten przykład, generują kod IL dla konstruktora statycznego, który jest podobny do tego.

    .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 przedstawiono wyjątek TypeInitializationException zgłoszony przez konstruktor statyczny wygenerowany przez kompilator. Klasa Example zawiera pole static (w języku C#) lub Shared (w Visual Basic) typu TestClass tworzone przez przekazanie wartości 3 do konstruktora klasy. Ta wartość jest jednak niedozwolona; dozwolone są tylko wartości 0 lub 1. W rezultacie konstruktor klasy TestClass zgłasza błąd ArgumentOutOfRangeException. Ponieważ ten wyjątek nie jest obsługiwany, jest umieszczany w wyjątku 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()
    

    Zwróć uwagę, że komunikat o wyjątku wyświetla informacje o właściwości InnerException.

  • Brak zestawu lub pliku danych

    Częstą przyczyną wyjątku TypeInitializationException 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 wyjątek TypeInitializationException i wyświetli dane wyjściowe pokazane w przykładzie. Należy pamiętać, że komunikat o wyjątku zawiera informacje o właściwości InnerException. W takim przypadku wyjątek wewnętrzny FileNotFoundException zostaje zgłoszony, ponieważ środowisko uruchomieniowe nie może odnaleźć zależnego zestawu.

    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 zgłoszono 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 przekroczenia czasu dopasowania wyrażeń regularnych

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 wartości TimeSpan dla właściwości "REGEX_DEFAULT_MATCH_TIMEOUT" dla metody AppDomain.SetData. Przedział czasu musi być prawidłowym obiektem TimeSpan, który jest większy niż zero i krótszy niż około 24 dni. Jeśli te wymagania nie zostaną spełnione, próba ustawienia domyślnej wartości limitu czasu zgłasza ArgumentOutOfRangeException, która z kolei jest opakowana w wyjątek TypeInitializationException.

W poniższym przykładzie przedstawiono TypeInitializationException zgłaszaną, 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 wartość TimeSpan 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: {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()

Kalendarze i dane kulturowe

Jeśli próbujesz utworzyć wystąpienie kalendarza, ale środowisko uruchomieniowe nie może utworzyć wystąpienia obiektu CultureInfo, który odpowiada kalendarzowi, zgłaszany jest wyjątek TypeInitializationException. Ten wyjątek może zostać zgłoszony przez następujące konstruktory klas kalendarza:

Ponieważ dane kulturowe tych kultur powinny być dostępne we wszystkich systemach, rzadko należy napotkać ten wyjątek.