2012-02-17 12 views
12

No creo que el código generado verifique si la clase se ha inicializado cada vez que accede a un miembro estático (que incluye funciones). Creo que verificar cada acceso sería ineficiente. Miré a §17.11 en ECMA 334 y dice¿Cómo sabe C# cuándo ejecutar un constructor estático?

La ejecución de un constructor estático es provocada por el primero de los siguientes eventos a ocurrir dentro de un dominio de aplicación:

  • Una instancia de la clase es creada.
  • Se hace referencia a cualquiera de los miembros estáticos de la clase.

Parece que la forma de averiguar cuándo 'primero' que ocurre no está definido. No puedo pensar en ninguna manera de hacerlo, sino de verificarlo todo el tiempo. ¿Cómo podría hacerse?

+3

relacionados, para el caso estático: http://csharpindepth.com/Articles/General/Beforefieldinit.aspx - es no trivial –

+0

no que es la cuestión de establecer un puntero de función en una ubicación diferente después de la primera ¿llamada? Al principio apunta al cargador de clases o lo que sea, luego al cuerpo de la función ... – user1096188

+1

@Marc: que trata de llamar al constructor estático ANTES de que se permita el primer acceso a un miembro estático, no cómo se detecta el primer acceso . –

Respuesta

5

Cuando genera código en tiempo de ejecución, tiene muchas opciones. Puede llamar a un puntero de función NULL, detectar la infracción de acceso, ejecutar el constructor estático, compilar el getter de propiedad, actualizar el puntero de función y continuar. O haga que la propiedad getter invoque una función auxiliar que ejecute el constructor estático y reescriba el código getter sin la llamada a la función auxiliar. O inserte un cheque en cada acceso de miembro estático, que cuando golpea recompila la función de llamada con la marca eliminada.

16

Cuando tenga un problema que resolver, una buena técnica es: resolver un problema aún más difícil, de modo que la solución de su pequeño problema se resuelva mediante la solución del problema más difícil.

El CLR tiene un problema mucho más difícil de resolver: tiene que ejecutar el jitter exactamente una vez en cada método justo antes de que se llame al método por primera vez. Si el CLR puede resolver ese problema, obviamente puede resolver el sub-problema comparativamente trivial de detectar cuándo se necesita ejecutar un ctor estático.

Tal vez su pregunta debería ser "¿cómo sabe la fluctuación de fase cuándo poner en marcha un método por primera vez?"

+0

Interesante. Simplemente asumí que el JIT en sistemas no embebidos simplemente lo ataca todo de inmediato y está listo para cargar nuevos dlls. Supuse que los sistemas embebidos se usan con anticipación. Mala suposición, especialmente cuando el código grande entra en juego. +1 para los pensamientos –

+1

@ acidzombie24 en realidad, algunos sistemas incorporados no JIT/AOT ** en absoluto ** - Micro Framework es un intérprete IL (cruza los dedos que no tengo esto al revés ...) –

+0

y algunos sistemas como.Net Compact Framework JIT solo cosas básicas, p. obtener propiedad es una llamada de función –

Cuestiones relacionadas