.NET: ¿Se llaman a los constructores estáticos cuando una constante es acceso?
-
26-10-2019 - |
Pregunta
Así que esto es lo que estoy pensando ...
public class MyClass
{
public const string MyConstant = "MyConstantValue";
private static MyClass DefaultInstance;
static MyClass()
{
DefaultInstance = new MyClass();
}
}
...
NotificationService.RegisterForNotification(MyClass.MyConstant, Callback);
Esto funcionará o si necesito usar algo como un static readonly
propiedad ¿Campo para activar el constructor estático?
Solución
El uso de una constante no necesariamente resulta en un acceso de miembro que cause que se llame al constructor estático. El compilador puede (alentado, incluso) sustituir el valor de la constante en el momento de la compilación.
Su solución sugerida de static readonly
debería estar bien, aunque readonly
sugiere un campo, no una propiedad. Las propiedades son de solo lectura cuando no tienen setter, el readonly
La palabra clave no está involucrada.
Un ejemplo simple:
class HasSConstructor
{
internal const int Answer = 42;
static HasSConstructor()
{
System.Console.WriteLine("static constructor running");
}
}
public class Program
{
public static void Main()
{
System.Console.WriteLine("The answer is " + HasSConstructor.Answer.ToString());
}
}
Salida bajo .NET 4.0:
La respuesta es 42
¡El constructor estático nunca funciona!
Otros consejos
El constructor estático se llama automáticamente antes de crear la primera instancia o se hace referencia a cualquier miembro estático. Mira aquí: MSDN: constructores estáticos
Por cierto, los campos constantes son inherentemente estáticos, pero como señalaron, pueden (y probablemente) ser sustituidos por el valor en sí.
El constructor estático no se llamará si solo está accediendo a constantes públicas. Por ejemplo, considere esta clase:
class Testo
{
public const string MyValue = "Hello, world";
public static readonly int xyzzy;
static Testo()
{
Console.WriteLine("In static constructor");
xyzzy = 27;
}
}
Ahora, en otra clase, ejecute:
Console.WriteLine(Testo.MyValue);
Console.WriteLine(Testo.xyzzy);
Su salida será:
Hello, world
In static constructor
27
Las constantes se elevan de la clase en el momento de la compilación. Entonces el valor de Testo.MyValue
no hace referencia al Testo
clase en tiempo de ejecución. El constructor estático no se llama hasta que llame a algo que requiere inicialización.
Entonces, sí, necesitas acceder a algo como un static readonly
Si desea asegurarse de que se llame al constructor.
No, no necesitas eso. El constructor estático se llama cuando la clase se carga.