System.TypeInitializationException (clase)
En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.
Cuando el inicializador de clase no logra inicializar un tipo, se crea una excepción TypeInitializationException y se pasa una referencia a la excepción producida por el inicializador de clase del tipo. La propiedad InnerException de TypeInitializationException contiene la excepción subyacente.
Normalmente, la excepción TypeInitializationException refleja una condición grave (el tiempo de ejecución no puede crear instancias de un tipo) que impide que una aplicación continúe. Normalmente, TypeInitializationException se inicia en respuesta a algún cambio en el entorno en ejecución de la aplicación. Por tanto, aparte de posiblemente para solucionar problemas de código de depuración, la excepción no se debe controlar en un bloque try
/catch
. En su lugar, la causa de la excepción se debe investigar y eliminar.
TypeInitializationException usa HRESULT COR_E_TYPEINITIALIZATION
, que tiene el valor 0x80131534.
Para obtener una lista de valores de propiedad iniciales de una instancia de TypeInitializationException, consulte el TypeInitializationException constructores.
En las secciones siguientes se describen algunas de las situaciones en las que se inicia una excepción TypeInitializationException.
Constructores estáticos
El tiempo de ejecución llama automáticamente a un constructor estático, si existe, antes de crear una instancia de un tipo. Un desarrollador puede definir explícitamente los constructores estáticos. Si un constructor estático no se define de manera explícita, los compiladores crean automáticamente uno para inicializar cualquier miembro static
(en C# o F#) o Shared
(en Visual Basic) del tipo. Para más información sobre los constructores estáticos, vea Constructores estáticos.
Normalmente, una excepción TypeInitializationException se inicia cuando un constructor estático no puede crear instancias de un tipo. La propiedad InnerException indica por qué el constructor estático no ha podido crear instancias del tipo. Algunas de las causas más comunes de una excepción TypeInitializationException son las siguientes:
Una excepción no controlada en un constructor estático
Si se inicia una excepción en un constructor estático, se encapsula en una excepción TypeInitializationException y no se puede crear una instancia del tipo.
Lo que a menudo dificulta la solución de problemas de esta excepción es que los constructores estáticos no siempre se definen explícitamente en el código fuente. Existe un constructor estático en un tipo si:
Se ha definido explícitamente como miembro de un tipo.
El tipo tiene variables
static
(en C# o F#), oShared
(en Visual Basic) que se declaran e inicializan en una sola instrucción. En este caso, el compilador de lenguaje genera un constructor estático para el tipo. Puede inspeccionarlo mediante una utilidad como el desensamblador de IL. Por ejemplo, cuando los compiladores de C# y VB compilan el ejemplo siguiente, generan el IL para un constructor estático similar al siguiente:
.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
En el ejemplo siguiente se muestra una excepción TypeInitializationException iniciada por un constructor estático generado por el compilador. La clase
Example
incluye un campostatic
(en C#) oShared
(en Visual Basic) de tipoTestClass
del que se crea una instancia al pasar un valor de 3 a su constructor de clase. Pero ese valor no es válido; solo se permiten valores de 0 o 1. Como resultado, el constructor de claseTestClass
inicia una excepción ArgumentOutOfRangeException. Como esta excepción no se controla, se encapsula en una excepción 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()
Tenga en cuenta que el mensaje de excepción muestra información sobre la propiedad InnerException.
Falta un ensamblado o un archivo de datos
Una causa común de una excepción TypeInitializationException es la falta de un ensamblado o un archivo de datos que estaba presente en los entornos de desarrollo y pruebas de una aplicación en su entorno de tiempo de ejecución. Por ejemplo, puede compilar el ejemplo siguiente en un ensamblado denominado Missing1a.dll mediante esta sintaxis de línea de comandos:
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
Después, puede compilar el ejemplo siguiente en un archivo ejecutable denominado Missing1.exe mediante la inclusión de una referencia a Missing1a.dll:
csc Missing1.cs /r:Missing1a.dll
vbc Missing1.vb /r:Missing1a.dll
Pero si cambia el nombre, mueve o elimina Missing1a.dll y ejecuta el ejemplo, inicia una excepción TypeInitializationException y genera la salida que se muestra en el ejemplo. Tenga en cuenta que el mensaje de excepción muestra información sobre la propiedad InnerException. En este caso, la excepción interna esFileNotFoundException, que se inicia porque el tiempo de ejecución no encuentra el ensamblado dependiente.
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()
Nota:
En este ejemplo, se ha iniciado una excepción TypeInitializationException porque no se ha podido cargar un ensamblado. También se puede iniciar la excepción si un constructor estático intenta abrir un archivo de datos, como un archivo de configuración, un archivo XML o un archivo que contiene datos serializados, que no puede encontrar.
Valores de tiempo de espera de coincidencia de expresiones regulares
Puede establecer el valor de tiempo de espera predeterminado para una operación de coincidencia de patrones de expresión regular por cada dominio de aplicación. El tiempo de espera se define mediante la especificación de un valor TimeSpan para la propiedad "REGEX_DEFAULT_MATCH_TIMEOUT" en el método AppDomain.SetData. El intervalo de tiempo debe ser un objeto TimeSpan válido mayor que cero y menor que aproximadamente 24 días. Si no se cumplen estos requisitos, el intento de establecer el valor de tiempo de espera predeterminado inicia una excepción ArgumentOutOfRangeException que, a su vez, se encapsula en una excepción TypeInitializationException.
En el ejemplo siguiente se muestra la excepción TypeInitializationException que se inicia cuando el valor asignado a la propiedad "REGEX_DEFAULT_MATCH_TIMEOUT" no es válido. Para eliminar la excepción, establezca la propiedad "REGEX_DEFAULT_MATCH_TIMEOUT" en un valor TimeSpan mayor que cero y menor que aproximadamente 24 días.
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()
Calendarios y datos de referencias culturales
Si intenta crear una instancia de un calendario, pero el tiempo de ejecución no puede crear una instancia del objeto CultureInfo que se corresponde a ese calendario, inicia una excepción TypeInitializationException. Esta excepción se puede iniciar mediante los siguientes constructores de clase de calendario:
- El constructor sin parámetros de la clase JapaneseCalendar.
- El constructor sin parámetros de la clase KoreanCalendar.
- El constructor sin parámetros de la clase TaiwanCalendar.
Como los datos de estas referencias culturales deben estar disponibles en todos los sistemas, rara vez debería encontrar esta excepción.