2010-11-15 20 views
11

¿Existe alguna forma en C# o .net IL para forzar a una clase que tiene un inicializador de tipo (constructor estático) a cargarse a sí mismo, sin acceder a ninguno de sus parámetros?Forcing class load

Suponiendo Tengo la clase

public static class LogInitialization { 
    static LogInitialization() { 
     System.Console.WriteLine("Initialized"); 
    } 
} 

¿Hay una manera de conseguir esta línea para imprimir?

Tenga en cuenta que la clase es estática, por lo que no puedo instanciarla para forzar la inicialización, y no tiene miembros públicos, por lo que no puedo acceder a ellos para iniciarla.

Respuesta

12

Revolviendo en la especificación CLI, he encontrado una referencia al método RuntimeHelpers.RunClassConstructor

Si un idioma desea proporcionar un comportamiento más rígida - por ejemplo, el tipo de inicialización activa automáticamente la ejecución de valores de inicialización de la clase base, en una tapa para -to-inferior - a continuación, puede hacerlo de dos formas:

  • definir campos y de código estático ocultos en cada constructor de la clase que toca el campo estático oculta de su clase base y/o interfaces que implementa, o
  • realizando llamadas explícitas a System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (ver Partición IV).
+2

Para usar esto, pase el resultado de la propiedad 'TypeHandle' en su instancia de' Type'. – Sam

7

Normalmente creo un método dummy (vacío) Init en clases con constructores estáticos para forzar la ejecución del constructor estático. es decir.

public static void Initialize() 
{ 
    // this will force your static constructor to execute, obviously 
} 

Dicho esto, siempre se puede ir por el Type.TypeInitializer con la reflexión ... http://msdn.microsoft.com/en-us/library/system.type.typeinitializer.aspx

EDIT: Otra cosa que he hecho en el pasado, es crear un atributo llamado RequiresInitializationAttribute entonces en AssemblyLoad, escanee el ensamblado para ver los tipos con dicho atributo y use type.TypeInitializer para forzar al constructor estático a ejecutar cuando se cargue el ensamblaje que lo contiene.

Supongo que la verdadera pregunta, como de costumbre, es ... ¿qué estás tratando de lograr?

+0

Sí, podría simplemente llamar al '.cctor' mismo, simplemente no estaba seguro de si eso impediría que el CLR lo llamara nuevamente. – configurator

+0

¡Además, se produce un error al llamar al inicializador de tipo en tipos estáticos! "No se puede crear una instancia de A porque es una clase abstracta". No veo por qué ese mensaje está relacionado, pero eso es lo que obtengo. – configurator

+0

En cuanto a lo que estoy tratando de lograr, básicamente estoy compilando desde un lenguaje que tiene reglas estrictas sobre cuándo deben cargarse las clases, por lo que quiero cargarlas en los momentos adecuados. – configurator