A continuación se muestran dos formas diferentes de inicializar campos de solo lectura estáticos. ¿Hay alguna diferencia entre los dos enfoques? En caso afirmativo, ¿cuándo se debe preferir uno al otro?iniciador de campo de solo lectura estático frente a la inicialización de constructor estático
Respuesta
Hay una diferencia sutil entre estos dos, que se puede ver en el código IL: al colocar un constructor estático explícito, el compilador C# no debe marcar el tipo como beforefieldinit. El campo anterior afecta cuando se ejecuta el inicializador de tipo y conocer esto es útil al escribir lazy singletons in C#, por ejemplo.
En resumen, la diferencia es la siguiente:
.class private auto ansi beforefieldinit A
.class private auto ansi B
En todos los demás aspectos que son los mismos. La salida del reflector:
Clase A:
.class private auto ansi beforefieldinit A
extends [mscorlib]System.Object
{
.method private hidebysig specialname rtspecialname static void .cctor() cil managed
{
.maxstack 8
L_0000: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection> WebConfigurationManager::ConnectionStrings
L_0005: ldstr "SomeConnection"
L_000a: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection>::get_Item(!0)
L_000f: ldfld string Connection::ConnectionString
L_0014: stsfld string A::connectionString
L_0019: ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: ret
}
.field private static initonly string connectionString
}
Clase B:
.class private auto ansi B
extends [mscorlib]System.Object
{
.method private hidebysig specialname rtspecialname static void .cctor() cil managed
{
.maxstack 8
L_0000: nop
L_0001: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection> WebConfigurationManager::ConnectionStrings
L_0006: ldstr "SomeConnection"
L_000b: callvirt instance !1 [mscorlib]System.Collections.Generic.Dictionary`2<string, class Connection>::get_Item(!0)
L_0010: ldfld string Connection::ConnectionString
L_0015: stsfld string B::connectionString
L_001a: ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib]System.Object::.ctor()
L_0006: ret
}
.field private static initonly string connectionString
}
Ellos son esencialmente los mismos, pero si le sucede que tiene tanto una asignación de sólo lectura a un campo estático y un constructor de tipo estático, la asignación de sólo lectura que ocurra primero.
El beforefieldinit atributo indica cómo ocurre la inicialización.
En el caso de una inicialización explícita del constructor estático, la inicialización del miembro estático ocurre en el momento en que se accede al tipo. En el ejemplo dado en el caso de la clase A, la inicialización ocurrirá cuando se refiera por primera vez connectionString, mientras que en el caso de la clase B la inicialización ocurrirá la primera vez que se refiere la clase de tipo B, no necesariamente accediendo a connectionString.
Solo C# (.NET 4.0) nos proporciona control sobre cómo pueden inicializarse los miembros estáticos. Con VB.NET, solo es posible el método no antes del campo, mientras que con C++/CLI solo es posible el mecanismo beforefieldinit.
- 1. Inicialización de campo estático Java
- 2. ¿Cómo puede ser nulo un campo estático de solo lectura?
- 3. C# privado, estático y de solo lectura
- 4. Inicialización de tipo (constructor estático) manejo de excepciones
- 5. ¿Cómo funciona la inicialización del campo estático en C#?
- 6. Asignación al campo de solo lectura estático de la clase base
- 7. Inicialización del elemento estático estático en la clase de plantilla
- 8. Bloque estático vs método estático - inicialización de campos estáticos
- 9. Inicialización de campo estático en la clase de plantilla en C++
- 10. constructor público y constructor estático
- 11. ¿Constructor estático llamado después del constructor de la instancia?
- 12. C# Genérico estático Constructor
- 13. Constructor estático en VB.NET
- 14. Constructor estático y excepciones
- 15. constructor estático en C#
- 16. Código de constructor estático funciona más lento
- 17. Miembro estático fallo objeto de inicialización
- 18. ¿Determina el orden de inicialización estático después de la compilación?
- 19. Excepción en el constructor estático
- 20. estático de inicialización en OpenCV Android
- 21. del campo estático
- 22. Estado de la aplicación ASP.NET frente a un objeto estático
- 23. Condición de carrera en C# constructor estático
- 24. ¿Hay un constructor estático o un inicializador estático en Python?
- 25. destructor estático
- 26. Llamar explícitamente al constructor estático
- 27. Acceso al método estático al constructor no estático?
- 28. equivalente constructor estático en Objective-C?
- 29. vaciado estático frente dinámico reparto
- 30. sincronizar el acceso a un campo estático