Comment utiliser les variables globales en C #?

101

Comment déclarer une variable pour que chaque classe (* .cs) puisse accéder à son contenu, sans référence d'instance?

Mas Ajum
la source

Réponses:

123

Dans C#vous ne pouvez pas définir de vraies variables globales (dans le sens où elles n'appartiennent à aucune classe).

Cela étant dit, l'approche la plus simple que je connaisse pour imiter cette fonctionnalité consiste à utiliser a static class, comme suit:

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
}

Vous pouvez ensuite récupérer les valeurs définies n'importe où dans votre code (à condition que cela fasse partie du même namespace):

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

Afin de gérer différents espaces de noms, vous pouvez soit:

  • déclarer la Globalsclasse sans l'inclure dans un spécifique namespace(afin qu'elle soit placée dans l'espace de noms global de l'application);
  • insérez la directive using appropriée pour récupérer les variables d'un autre namespace.
Tommaso Belluzzo
la source
@Zarathos est-ce que la classe doit également être statique?
kosnkov
4
Eh bien, ce n'est pas nécessaire mais je ne vois pas pourquoi vous devriez l'instancier.
Tommaso Belluzzo
Si vous devez instancier sa définition par définition et non plus "globale", ne faisant pas partie de l'état de l'application
Viking
Salut, quelle serait la différence si je ne tapais pas le mot-clé statique dans la classe? J'ai seulement rendu la chaîne FILE_NAME statique, j'ai essayé et cela fonctionnait toujours pour moi.
Tomer Cahal le
1
Sans l'attribut static, votre classe sera instanciable (Globals g = new Globals ()). Cela ne modifie pas le comportement des variables statiques déclarées à l'intérieur, mais cela n'a pas l'air vraiment utile.
Tommaso Belluzzo le
74

Il n'y a pas de variable globale en C #. Période.

Vous pouvez avoir des membres statiques si vous le souhaitez:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}
Federico Berasategui
la source
Bien que je sois d'accord, pourriez-vous expliquer pourquoi il n'existe pas de variable globale en C #? J'essayais de penser à une bonne raison pour laquelle cet staticexemple que vous avez fourni ne peut pas vraiment être considéré comme une variable globale.
cregox
3
@cawas parce que le concept même de "variable globale" (suspendue de nulle part, flottant dans les limbes, n'appartenant à aucune classe) va à l'encontre de la nature même de la POO. et C # est strictement orienté objet.
Federico Berasategui
Oui, c'est tout le concept avec lequel je suis d'accord. Mais en créant ce membre statique, vous venez de créer une sorte de variable globale. En quoi cela diffère-t-il de la variable globale dont vous avez dit qu'elle n'existe pas? J'aimerais voir un exemple pratique.
cregox
1
J'ai l'impression que vous éludez ma question ou que je ne suis pas clair. Mais je l'ai déjà répondu. Ici: stackoverflow.com/a/20010543/274502
cregox
7
Je réalise maintenant ce que je voulais dire, c'est que les membres statiques sont conceptuellement et pratiquement des variables globales (sauf peut-être pour ce truc de tas , qui ne fait la différence que si vous n'écrivez pas du code non sécurisé ou si vous effectuez une sorte d'interopérabilité lourde avec du code non managé ). Donc je ne sais pas pourquoi quelqu'un dirait " il n'y a pas de variable globale dans csharp ". Cela m'a beaucoup dérouté.
cregox
23

Commencez par examiner si vous avez vraiment besoin d'une variable globale à la place, en l'utilisant de manière flagrante sans tenir compte de votre architecture logicielle.

Supposons qu'il passe le test. En fonction de l'utilisation, Globals peut être difficile à déboguer avec les conditions de concurrence et beaucoup d'autres "mauvaises choses", il est préférable de les aborder sous un angle où vous êtes prêt à gérer de telles mauvaises choses. Alors,

  1. Enveloppez toutes ces variables globales dans une seule staticclasse (pour plus de facilité de gestion).
  2. Avoir des propriétés au lieu de champs (= 'variables'). De cette façon, vous disposez de mécanismes pour résoudre les problèmes d'écriture simultanée sur Globals à l'avenir.

Le plan de base pour une telle classe serait:

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.
}

Utilisation à partir d'autres classes (dans le même espace de noms)

// Read
bool areWeAlive = Globals.Expired;

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

Une fonctionnalité utile pour cela est using static

Comme d'autres l'ont dit, vous devez créer une classe pour vos globaux:

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

Mais vous pouvez l'importer comme ceci afin de ne plus écrire le nom de la classe devant ses propriétés statiques:

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