C#でグローバル変数を使用する方法


101

すべてのクラス(* .cs)がインスタンス参照なしでコンテンツにアクセスできるように変数を宣言するにはどうすればよいですか?

回答:


123

ではC#、真のグローバル変数を定義することはできません(それらがどのクラスにも属していないという意味で)。

つまり、この機能を模倣するために私が知っている最も簡単なアプローチはstatic class、次のようにを使用することです。

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
}

次に、コード内の任意の場所に定義された値を取得できます(同じの一部である場合namespace):

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

異なる名前空間を処理するには、次のいずれかを実行できます。

  • Globals特定に含めずにクラスを宣言しますnamespace(グローバルアプリケーションの名前空間に配置されます)。
  • 別のから変数を取得するための適切なusingディレクティブを挿入しますnamespace

@Zarathosクラスも静的である必要がありますか?
kosnkov

4
それは必須ではありませんが、なぜインスタンス化する必要があるのか​​わかりません。
Tommaso Belluzzo

定義ごとにインスタンス化する必要がある場合、「グローバル」ではなく、アプリケーション状態の一部ではありません
Viking

こんにちは、クラスに静的キーワードを入力しないとどうなりますか?文字列FILE_NAMEを静的にしただけで、試しましたが、それでも機能しました。
Tomer Cahal

1
static属性がなければ、クラスはインスタンス化可能になります(Globals g = new Globals())。内部で宣言された静的変数の動作は変更しませんが、実際には役に立たないようです。
Tommaso Belluzzo

74

C#にはグローバル変数などはありません。限目。

必要に応じて、静的メンバーを持つことができます。

public static class MyStaticValues
{
   public static bool MyStaticBool {get;set;}
}

私も同意しますが、C#にはグローバル変数などがない理由を詳しく説明していただけますか?staticあなたが提供したそのまさにその例が本当にグローバル変数と見なすことができないという正当な理由を考えようとしていました。
cregox 2013年

3
@cawasは、「グローバル変数」の概念(どこからもぶら下がって、リンボに浮かんでいて、どのクラスにも属していない)がOOPの本質に反するためです。C#は厳密にオブジェクト指向です。
フェデリコベラサテギ2013年

はい、それは私が同意するすべての概念です。しかし、その静的メンバーを作成することで、一種のグローバル変数を作成しただけです。あなたが言っていなかったグローバル変数とどう違うのですか?実用的な例を見せてください。
cregox 2013年

1
あなたは私の質問を回避しているか、私は明確ではないようです。しかし、私はそれをすでに答えさせました。ここ:stackoverflow.com/a/20010543/274502
cregox '15年

7
静的メンバーは概念的かつ実質的にグローバル変数であることを私が今理解していることを理解しています(おそらく、そのヒープの事柄を除いて、安全でないコードを記述したり、アンマネージコードとある種の重い相互運用を行ったりしない限り、違いが生じます)。だから、なぜcsharpにはグローバル変数のようなものはない」と誰が言うのかわかりません。それは私をとても混乱させました。
cregox 2013年

23

まず、ソフトウェアアーキテクチャを考慮せずに露骨にグローバル変数を使用する代わりに、グローバル変数が本当に必要かどうかを調べます。

テストに合格したとしましょう。使用方法によっては、競合状態やその他の多くの「悪いこと」でグローバルをデバッグするのは難しい場合があります。そのような悪いことを処理する準備ができている角度からアプローチすることをお勧めします。そう、

  1. そのようなすべてのグローバル変数を単一のstaticクラスにラップします(管理性のため)。
  2. fields(= 'variables')の代わりにプロパティがあります。このようにして、将来のGlobalsへの同時書き込みの問題に対処するためのメカニズムがいくつかあります。

このようなクラスの基本的な概要は次のとおりです。

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

他のクラスからの使用(同じ名前空間内)

// Read
bool areWeAlive = Globals.Expired;

// Write
// past deadline
Globals.Expired = true;

4

これに役立つ機能は using static

他の人が言ったように、あなたはあなたのグローバルのためのクラスを作らなければなりません:

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

ただし、静的プロパティの前にクラス名を書き込まないように、次のようにインポートできます。

using static Globals;
[...]
Console.WriteLine("Pi is " + PI);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.