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