Wie verwende ich globale Variablen in C #?

101

Wie deklariere ich eine Variable, damit jede Klasse (* .cs) ohne Instanzreferenz auf ihren Inhalt zugreifen kann?

Mas Ajum
quelle

Antworten:

122

In können C#Sie keine echten globalen Variablen definieren (in dem Sinne, dass sie keiner Klasse angehören).

Abgesehen davon besteht der einfachste Ansatz, den ich kenne, um diese Funktion nachzuahmen, darin, a static classwie folgt zu verwenden:

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
}

Sie können die definierten Werte dann an einer beliebigen Stelle in Ihrem Code abrufen (vorausgesetzt, sie sind Teil desselben namespace):

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

Um mit verschiedenen Namespaces umzugehen, können Sie entweder:

  • Deklarieren Sie die GlobalsKlasse, ohne sie in eine bestimmte Klasse aufzunehmen namespace(damit sie in den globalen Anwendungsnamespace eingefügt wird).
  • Fügen Sie die richtige using-Direktive ein, um die Variablen von einer anderen abzurufen namespace.
Tommaso Belluzzo
quelle
@ Zarathos Muss die Klasse auch statisch sein?
Kosnkov
4
Nun, es ist nicht notwendig, aber ich verstehe nicht, warum Sie es instanziieren sollten.
Tommaso Belluzzo
Wenn Sie seine Definition per Definition nicht mehr "global" instanziieren müssen, gehört sie nicht mehr zum Anwendungsstatus
Viking
Hallo, was wäre der Unterschied, wenn ich das statische Schlüsselwort nicht in die Klasse eingeben würde? Ich habe nur den String FILE_NAME statisch gemacht, ich habe es versucht und es hat immer noch für mich funktioniert.
Tomer Cahal
1
Ohne das statische Attribut ist Ihre Klasse instanziierbar (Globals g = new Globals ()). Es ändert nichts am Verhalten der darin deklarierten statischen Variablen, sieht aber nicht wirklich nützlich aus.
Tommaso Belluzzo
74

In C # gibt es keine globale Variable. Zeitraum.

Sie können statische Mitglieder haben, wenn Sie möchten:

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}
Federico Berasategui
quelle
Könnten Sie bitte erläutern, warum es in C # keine globale Variable gibt? Ich habe versucht, einen guten Grund zu finden, warum staticgenau das Beispiel, das Sie angegeben haben, nicht wirklich als globale Variable angesehen werden kann.
Cregox
3
@cawas, weil das Konzept einer "globalen Variablen" (die aus dem Nichts hängt, in der Schwebe schwebt und keiner Klasse angehört) der Natur von OOP widerspricht. und C # ist streng objektorientiert.
Federico Berasategui
Ja, das ist alles Konzept, dem ich zustimme. Aber indem Sie dieses statische Mitglied erstellt haben, haben Sie gerade eine Art globales var erstellt. Wie unterscheidet sich das von der globalen Var, von der Sie sagten, dass sie nicht existiert? Ich würde gerne ein praktisches Beispiel sehen.
Cregox
1
Ich habe das Gefühl, dass Sie meiner Frage entweder ausweichen oder mir nicht klar ist. Aber ich habe es schon beantwortet bekommen. Hier: stackoverflow.com/a/20010543/274502
Cregox
7
Mir ist jetzt klar, dass ich damit gemeint habe, dass statische Mitglieder konzeptionell und praktisch globale Variablen sind (außer vielleicht für diese Heap-Sache , die nur dann einen Unterschied macht, wenn Sie unsicheren Code schreiben oder eine schwere Interaktion mit nicht verwaltetem Code ausführen ). Ich weiß also nicht, warum jemand sagen sollte, dass es in csharp keine globale Variable gibt . Es hat mich sehr verwirrt.
Cregox
23

Prüfen Sie zunächst, ob Sie wirklich eine globale Variable benötigen, anstatt sie offen zu verwenden, ohne Rücksicht auf Ihre Softwarearchitektur.

Nehmen wir an, es besteht den Test. Abhängig von der Verwendung kann es schwierig sein, Globals mit Rennbedingungen und vielen anderen "schlechten Dingen" zu debuggen. Es ist am besten, sie aus einem Blickwinkel zu betrachten, in dem Sie bereit sind, mit solchen schlechten Dingen umzugehen. So,

  1. Wickeln Sie alle diese globalen Variablen in eine einzige staticKlasse (aus Gründen der Verwaltbarkeit).
  2. Haben Sie Eigenschaften anstelle von Feldern (= 'Variablen'). Auf diese Weise haben Sie einige Mechanismen, um Probleme mit gleichzeitigen Schreibvorgängen an Globals in Zukunft zu beheben.

Der Grundriss für eine solche Klasse wäre:

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

Verwendung aus anderen Klassen (innerhalb desselben Namespace)

// Read
bool areWeAlive = Globals.Expired;

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

Eine nützliche Funktion hierfür ist using static

Wie andere gesagt haben, müssen Sie eine Klasse für Ihre Globals erstellen:

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

Sie können es jedoch folgendermaßen importieren, um den Klassennamen nicht mehr vor seine statischen Eigenschaften zu schreiben:

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