namespace MyNameSpace
{
static class MyClass
{
static MyClass()
{
//Authentication process.. User needs to enter password
}
public static void MyMethod()
{
//Depends on successful completion of constructor
}
}
class Program
{
static void Main(string[] args)
{
MyClass.MyMethod();
}
}
}
Aquí está la secuencia que asumí
- Inicio del constructor estático
- Fin del constructor estático
- Inicio de principal
- Inicio de MyMethod
- Fin de principal
Ahora, en cualquier escenario, si 4 comenzará antes de 2, estoy jodido. ¿Es posible?
c#
c#-4.0
static-constructor
om471987
fuente
fuente
Respuestas:
Aquí solo hizo una pregunta, pero hay una docena de preguntas que debería haber hecho, así que las responderé todas.
cctor
)No. La secuencia correcta es:
El CLR puede cambiar el orden en el que se ejecutan los inicializadores de campo estático en algunos casos. Vea la página de Jon sobre el tema para más detalles:
Las diferencias entre constructores estáticos e inicializadores de tipo
Si. Si el propio cctor llama a MyMethod, obviamente se llamará a MyMethod antes de que se complete el cctor.
Si. Si el cctor usa otro tipo cuyo cctor llama a MyMethod, entonces se llamará a MyMethod antes de que se complete el cctor MyClass.
No.
Si. El cctor terminará en un hilo antes de que se pueda llamar al método estático en cualquier hilo.
Se garantiza que el cctor se llamará como máximo una vez, sin importar cuántos subprocesos estén involucrados. Si dos hilos llaman a MyMethod "al mismo tiempo", corren. Uno de ellos pierde la carrera y bloquea hasta que el cctor MyClass completa el hilo ganador.
De Verdad.
Entonces tienes una condición clásica de inversión de orden de bloqueo. Su programa se bloquea. Siempre.
Si te duele cuando haces eso, deja de hacerlo . Nunca hagas algo que pueda bloquear un cctor.
Tampoco lo son las buenas ideas. Mi consejo es que debe encontrar una manera diferente de asegurarse de que se cumplan las condiciones previas de sus métodos que afectan la seguridad.
fuente
Según MSDN , un constructor estático:
Por lo tanto, se llamará al constructor estático antes de que
MyClass.MyMethod()
se invoque el método estático (suponiendo que no se invoca también durante la construcción estática o la inicialización del campo estático, por supuesto).Ahora, si está haciendo algo asincrónico en eso
static constructor
, entonces es su trabajo sincronizar eso.fuente
El n. ° 3 es en realidad el n. ° 1: la inicialización estática no comienza hasta el primer uso de la clase a la que pertenece.
Es posible si
MyMethod
se llama desde el constructor estático o desde un bloque de inicialización estático. Si no invocaMyMethod
directa o indirectamente desde su constructor estático, debería estar bien.fuente
static
inicialización se puede llamar antes del primer uso dependiendo de la elegibilidad para las optimizaciones.beforefieldinit
semántica) está determinado por si la clase C # tiene o no un constructor estático.De la documentación (el énfasis es mío):
fuente
Puede garantizar que 4 siempre vendrá después de 2 (si no crea una instancia de su clase a partir de su método estático), sin embargo, no ocurre lo mismo con 1 y 3.
fuente
Se llamará al constructor estático antes de que se ejecute mymethod. Sin embargo, si está jodido si se llama 4 antes que 2, le sugiero que reconsidere su diseño. De todos modos, no debería estar haciendo cosas complicadas en un constructor estático.
fuente
CLR garantiza que el constructor estático se ejecuta antes de que se acceda a cualquier miembro estático. Sin embargo, tu diseño huele un poco mal. Sería más sencillo hacer algo como esto:
static void Main(string[] args) { bool userIsAuthenticated = MyClass.AuthenticateUser(); if (userIsAuthenticated) MyClass.MyMethod(); }
Con su diseño, si la autenticación falla, la única forma de evitar que MyMethod se ejecute es lanzando una excepción.
fuente
Se garantiza que se haya llamado al constructor de una clase estática antes de que se ejecute cualquiera de sus métodos. Ejemplo:
class Program { static void Main(string[] args) { Console.WriteLine("Press enter"); Console.ReadLine(); Boop.SayHi(); Boop.SayHi(); Console.ReadLine(); } } static class Boop { static Boop() { Console.WriteLine("Hi incoming ..."); } public static void SayHi() { Console.WriteLine("Hi there!"); } }
Salida:
fuente
Aquí está el orden real en el que van las cosas:
Main
MyClass
constructor estáticoMyClass
constructor estáticoMyMethod
Main
fuente
O puede pasar por el depurador.
fuente