다음을 통해 공유


System.TypeInitializationException 클래스

이 문서는 이 API에 대한 참조 설명서를 보충하는 추가 설명을 제공합니다.

클래스 초기화 도중 형식 초기화에 실패하면, 해당 형식의 클래스 초기자에서 던져진 예외에 대한 참조가 만들어져 TypeInitializationException에 전달됩니다. InnerException 속성은 기본 TypeInitializationException 예외를 보유합니다.

일반적으로 예외는 애플리케이션이 TypeInitializationException 계속되지 않도록 하는 치명적인 조건(런타임이 형식을 인스턴스화할 수 없음)을 반영합니다. 애플리케이션 실행 환경에서 일부 변경이 발생할 경우 가장 흔히 TypeInitializationException이(가) throw됩니다. 따라서 디버그 코드 문제를 해결하는 것 외에는 예외를 블록에서 try/catch 처리해서는 안 됩니다. 대신 예외의 원인을 조사하고 제거해야 합니다.

TypeInitializationException 는 값이 0x80131534 HRESULT COR_E_TYPEINITIALIZATION를 사용합니다.

TypeInitializationException인스턴스의 초기 속성 값 목록은 TypeInitializationException 생성자를 참조하세요.

다음 섹션에서는 TypeInitializationException 예외가 발생하는 어떤 상황에 대해 설명합니다.

정적 생성자

정적 생성자(있는 경우)는 형식의 새 인스턴스를 만들기 전에 런타임에서 자동으로 호출됩니다. 정적 생성자는 개발자가 명시적으로 정의할 수 있습니다. 정적 생성자가 명시적으로 정의되지 않은 경우, 컴파일러는 C# 또는 F#의 static 멤버나 Visual Basic의 Shared 멤버를 초기화하기 위해 자동으로 생성자를 만듭니다. 정적 생성자에 대한 자세한 내용은 정적 생성자를 참조하세요.

가장 일반적으로 정적 생성자가 형식을 TypeInitializationException 인스턴스화할 수 없는 경우 예외가 발생합니다. 이 속성은 InnerException 정적 생성자가 형식을 인스턴스화할 수 없는 이유를 나타냅니다. 예외의 일반적인 원인 TypeInitializationException 은 다음과 같습니다.

  • 정적 생성자의 처리되지 않은 예외

    정적 생성자에서 예외가 throw 되면 해당 예외가 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
    

    다음 예제에서는 컴파일러가 생성한 정적 생성자가 던진 예외를 보여줍니다. 클래스에는 Example 형식의 static(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
    

    그런 다음 Missing1a.dll대한 참조를 포함하여 다음 예제를 Missing1.exe이라는 실행 파일로 컴파일할 수 있습니다.

    csc Missing1.cs /r:Missing1a.dll
    
    vbc Missing1.vb /r:Missing1a.dll
    

    그러나 Missing1a.dll 이름을 바꾸거나 이동하거나 삭제하고 예제를 실행하면 예외가 TypeInitializationException throw되고 예제에 표시된 출력이 표시됩니다. 예외 메시지에는 속성에 대한 정보가 포함됩니다 InnerException . 이 경우 내부 예외는 FileNotFoundException 런타임이 종속 어셈블리를 찾을 수 없기 때문에 throw되는 예외입니다.

    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 파일 또는 직렬화된 데이터가 포함된 파일과 같은 데이터 파일을 열려고 시도하는 경우에도 예외가 throw될 수 있습니다.

정규 표현식 일치 시간 제한 값

애플리케이션별 도메인 기준으로 정규식 패턴 일치 작업에 대한 기본 시간 제한 값을 설정할 수 있습니다. 시간 제한은 "REGEX_DEFAULT_MATCH_TIMEOUT" 속성의 TimeSpan 값을 메서드 내에서 지정하여 AppDomain.SetData 정의됩니다. 시간 간격은 0보다 크고 약 24일 미만인 유효한 TimeSpan 개체여야 합니다. 이러한 요구 사항이 충족되지 않으면 기본 시간 제한 값을 설정하려고 할 때 ArgumentOutOfRangeException가 throw되고, 이 값은 TypeInitializationException 예외로 래핑됩니다.

다음 예제는 "REGEX_DEFAULT_MATCH_TIMEOUT" 속성에 할당된 값이 유효하지 않을 때 던져지는 예외 TypeInitializationException를 보여줍니다. 예외를 제거하려면 "REGEX_DEFAULT_MATCH_TIMEOUT" 속성을 TimeSpan 0보다 크고 약 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 발생합니다. 이 예외는 다음 달력 클래스 생성자에 의해 throw될 수 있습니다.

  • 클래스의 매개 변수가 없는 생성자입니다 JapaneseCalendar .
  • 클래스의 매개 변수가 없는 생성자입니다 KoreanCalendar .
  • 클래스의 매개 변수가 없는 생성자입니다 TaiwanCalendar .

이러한 문화권에 대한 문화권 데이터는 모든 시스템에서 사용할 수 있어야 하므로 이 예외가 발생하는 경우는 거의 없습니다.