¿Cómo usar variables globales en C #?

101

¿Cómo declaro una variable para que cada clase (* .cs) pueda acceder a su contenido, sin una referencia de instancia?

Mas Ajum
fuente

Respuestas:

123

En C#no puede definir verdaderas variables globales (en el sentido de que no pertenecen a ninguna clase).

Dicho esto, el enfoque más simple que conozco para imitar esta característica consiste en usar a static class, de la siguiente manera:

public static class Globals
{
    public const Int32 BUFFER_SIZE = 512; // Unmodifiable
    public static String FILE_NAME = "Output.txt"; // Modifiable
    public static readonly String CODE_PREFIX = "US-"; // Unmodifiable
}

Luego puede recuperar los valores definidos en cualquier lugar de su código (siempre que sea parte del mismo namespace):

String code = Globals.CODE_PREFIX + value.ToString();

Para tratar con diferentes espacios de nombres, puede:

  • declarar la Globalsclase sin incluirla en una específica namespace(para que se coloque en el espacio de nombres de la aplicación global);
  • inserte la directiva using adecuada para recuperar las variables de otro namespace.
Tommaso Belluzzo
fuente
@Zarathos, ¿la clase también tiene que ser estática?
kosnkov
4
Bueno, no es necesario, pero no veo por qué debería crear una instancia.
Tommaso Belluzzo
Si tiene que crear una instancia de su definición, ya no es "global", no forma parte del estado de la aplicación
Viking
Hola, ¿cuál sería la diferencia si no escribiera la palabra clave estática en la clase? Solo hice la cadena FILE_NAME estática, lo intenté y aún me funcionó.
Tomer Cahal
1
Sin el atributo estático, su clase será instanciable (Globals g = new Globals ()). No altera el comportamiento de las variables estáticas declaradas en el interior, pero no parece realmente útil.
Tommaso Belluzzo
74

No existe una variable global en C #. Período.

Puede tener miembros estáticos si lo desea:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}
Federico Berasategui
fuente
Si bien estoy de acuerdo, ¿podría explicar por qué no existe una variable global en C #? Estaba tratando de pensar en una buena razón por la cual ese mismo staticejemplo que proporcionaste no puede realmente considerarse una var global.
cregox
3
@cawas porque el concepto mismo de una "variable global" (colgando de la nada, flotando en el limbo, sin pertenecer a ninguna clase) va en contra de la naturaleza misma de la POO. y C # está estrictamente orientado a objetos.
Federico Berasategui
Sí, ese es todo el concepto con el que estoy de acuerdo. Pero al hacer ese miembro estático, acaba de crear una especie de var global. ¿En qué se diferencia de la var global que dijiste que no existe? Me gustaría ver un ejemplo práctico.
cregox
1
Siento que o estás eludiendo mi pregunta o no lo tengo claro. Pero ya lo he respondido. Aquí: stackoverflow.com/a/20010543/274502
cregox
7
Ahora me doy cuenta de lo que quise decir es que los miembros estáticos son variables conceptuales y prácticamente globales (excepto tal vez por ese montón , que solo hace la diferencia a menos que esté escribiendo código inseguro o haciendo algún tipo de interoperación pesada con código no administrado ). Así que no sé por qué alguien diría " no existe una variable global en csharp ". Me confundió mucho.
cregox
23

Primero examine si realmente necesita una variable global en lugar de usarla descaradamente sin tener en cuenta la arquitectura de su software.

Supongamos que pasa la prueba. Dependiendo del uso, los Globals pueden ser difíciles de depurar con las condiciones de la carrera y muchas otras "cosas malas", es mejor abordarlas desde un ángulo en el que estés preparado para manejar cosas tan malas. Entonces,

  1. Envuelva todas esas variables globales en una sola staticclase (para mayor facilidad de administración).
  2. Tener propiedades en lugar de campos (= 'variables'). De esta manera, tiene algunos mecanismos para abordar cualquier problema con escrituras simultáneas en Globals en el futuro.

El esquema básico para tal clase sería:

public class Globals
{
    private static bool _expired;
    public static bool Expired 
    {
        get
        {
            // Reads are usually simple
            return _expired;
        }
        set
        {
            // You can add logic here for race conditions,
            // or other measurements
            _expired = value;
        }
    }
    // Perhaps extend this to have Read-Modify-Write static methods
    // for data integrity during concurrency? Situational.
}

Uso de otras clases (dentro del mismo espacio de nombres)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;
Sid
fuente
4

Una característica útil para esto es using static

Como han dicho otros, debes crear una clase para tus globales:

public static class Globals {
    public const float PI = 3.14;
}

Pero puede importarlo así para no escribir más el nombre de la clase delante de sus propiedades estáticas:

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
Zotta
fuente