DependencyProperty.AddOwner MSDN page ofrece un ejemplo con dos clases con miembros estáticos, y el miembro de una clase depende del miembro de la otra clase para la inicialización. Creo que MSDN está equivocado: el orden de inicialización de las variables estáticas no es confiable en C# just like it is in C++ o en otro lugar. Probablemente estoy equivocado porque la biblioteca WPF está escrita de esa manera y funciona bien. ¿Qué me estoy perdiendo? ¿Cómo es posible que el compilador de C# sepa la orden de inicialización segura?¿Cuál es el orden de inicialización de la variable estática en C#?
Respuesta
Está bien que un tipo dependa de que se inicialice otro tipo, siempre que no termine en un ciclo.
Básicamente esto está muy bien:
public class Child
{
static Child() {} // Added static constructor for extra predictability
public static readonly int X = 10;
}
public class Parent
{
static Parent() {} // Added static constructor for extra predictability
public static readonly int Y = Child.X;
}
El resultado está bien definido. Los inicializadores de variables estáticas Child
se ejecutan antes del primer acceso a cualquier campo estático en la clase, según la sección 10.5.5.1 de la especificación.
Esto no es sin embargo:
public class Child
{
public static readonly int Nasty = Parent.Y;
public static readonly int X = 10;
}
public class Parent
{
public static readonly int Y = Child.X;
}
En este último caso, ya sea terminar con Child.Nasty=0
, Parent.Y=10
, Child.X=10
o Child.Nasty=0
, Parent.Y=0
, Child.X=10
dependiendo de cuál se accede a la primera clase.
Al acceder a Parent.Y first
comenzará a inicializar Parent
primero. La inicialización de Child
se deberá dar cuenta de que Parent
debe inicializarse, pero el CLR sabe que ya se está inicializando, por lo que continúa independientemente, lo que lleva al primer conjunto de números porque Child.X
termina siendo inicializado antes de que su valor se use para Parent.Y
.
Al acceder a Child.Nasty
comenzará a inicializar Child
primero, que luego comenzará a inicializar Parent
. La inicialización de Parent
se dará cuenta de que Child
debe inicializarse, pero el CLR sabe que ya se está inicializando, por lo que continúa independientemente, lo que lleva al segundo conjunto de números.
No haga esto.
EDIT: Bueno, la explicación más detallada, como había prometido.
¿Cuándo se inicializa un tipo?
Si un tipo tiene un constructor estático, sólo se inicializará cuando se usa primero (ya sea cuando se hace referencia a un miembro estático, o cuando se crea una instancia). Si no tiene tiene un constructor estático , se puede inicializar earler. En teoría, también podría inicializarse más tarde ; en teoría, podría llamar a un constructor un método estático sin inicializar las variables estáticas, pero se debe inicializar antes de que se haga referencia a las variables estáticas.
¿Qué ocurre durante la inicialización?
Primero todas las variables estáticas reciben sus valores predeterminados (0, nulo etc.).
A continuación, las variables estáticas del tipo se inicializan en el orden textual . Si la expresión inicializador para una variable estática requiere otro tipo que ser inicializado, entonces ese otro tipo será inicializa completamente antes de que se le asigna el valor de la variable - menos que ya se está inicializando segundo tipo (debido a una dependencia cíclica ) En esencia, es un tipo cualquiera:
- Ya inicializada
- se inicializa en el momento
- No inicializado
inicialización se activa sólo si el tipo no se ha inicializado. Esto significa que cuando hay dependencias cíclicas, es posible observar el valor de una variable estática antes de que su valor inicial tenga asignado. Eso es lo que muestra mi ejemplo Child
/Parent
.
Después de que se hayan ejecutado todos los inicializadores de variables estáticas, se ejecuta el constructor estático .
Consulte la sección 10.12 de la especificación C# para obtener más información sobre todo esto.
Por demanda popular, aquí fue mi respuesta original cuando pensaba que la pregunta era sobre el orden de inicialización de variables estáticas dentro de una clase:
Las variables estáticas se inicializan en orden textual, según apartado 10.5.5.1 de la C# spec:
el campo estático inicializadores variables de una clase corresponden a una secuencia de asignaciones que se ejecutan en elorden textual en el que aparecen en la declaración de clase.
Tenga en cuenta que los tipos parciales lo hacen más complicado ya que no hay un único "orden de texto" canónico de la clase.
Si le preocupa el orden, siempre puede colocar su código en el constructor estático. Aquí es donde registro mis propiedades de dependencia.
No, creo que poco fiable no es la palabra correcta aquí.
En el escenario de un solo hilo verdadero, los miembros estáticos de la clase se inicializan cuando se accede por primera vez a cualquiera de los miembros estáticos del tipo en su código.
No conozco C++, pero sí solo en ciertos casos como en el entorno Multi threaded si dos tipos intentan acceder al recurso compartido y si eso es estático entonces es imposible saber quién ganará y cuál funcionará correctamente.
El ejemplo de MSDN es correcto y funcionará correctamente.
- 1. Orden de inicialización estática de C++
- 2. ¿Inicialización de variable estática?
- 3. inicialización de variable estática java
- 4. ¿El orden de inicialización de clase estática en C# es determinista?
- 5. ¿La inicialización de la variable de miembro estática de C++ es segura para subprocesos?
- 6. Inicialización de variable de clase estática dentro de la principal
- 7. ¿Cuál es la forma pitonica de inicialización de variable condicional?
- 8. Diferencia inicialización de línea variable estática o en el constructor estático en C#
- 9. ¿El orden de inicialización global de C++ ignora las dependencias?
- 10. Inicialización de variable en C++
- 11. Orden de inicialización del módulo de Python?
- 12. Java problema orden de inicialización, estática vs ejemplo campos
- 13. ¿Cuál es el tiempo de vida de una variable estática en una función de C++?
- 14. ¿Determina el orden de inicialización estático después de la compilación?
- 15. ¿Cuándo ocurre la inicialización de clase estática?
- 16. La inicialización de un puntero estática en C++
- 17. C++ miembros plantilla estática emisión de inicialización
- 18. ¿Por qué la inicialización de la variable de miembro entero (que no es const estática) no está permitida en C++?
- 19. C# variable de inicialización Pregunta
- 20. ¿Cuál es la diferencia entre una variable estática en C++ vs. C#?
- 21. inicialización de propiedad estática
- 22. variable estática global vs variable estática en la función?
- 23. C++ variable estática
- 24. Inicialización de la clase C++ que contiene la inicialización de variable de clase
- 25. ¿Por qué en C# el pedido es importante para la inicialización estática?
- 26. ¿Cuál es el tipo de lista de inicialización en la matriz C++?
- 27. una variable estática en c
- 28. Inicialización en C++ de variable de miembro estático no constante?
- 29. C#: La inicialización de una variable con el "uso"
- 30. ¿Es la inicialización estática una buena práctica de programación?
Gracias por su breve aparición, Most Holy. –
P.S. Su primera versión de publicación tuvo información útil. Devuélvelo por favor? –
@Nuevo en la ciudad: fue útil pero no relevante. Lo agregará como una nota secundaria. –