C#でグローバル変数はどうやって宣言するの?
C#グローバル変数が無いって聞いたけど、代わりはないの?
リストとかもグローバル変数として宣言したい!
コーディングをしていると、グローバル変数を使いたくなるケースはしばしばありますよね。C#でも当然そう思うことがあります。
しかし、C#にグローバル変数はありません。
こんにちは、元エンジニアでC#ライターの遠藤です!
今回の記事は、こんな方へ向けて書きました。
- C#でグローバル変数を使いたいと考えている方
 - グローバル変数が使えないと聞いて、どうすれば良いか悩んでいる方
 - 対応策を実際のコードを読んで理解したい方
 
この記事を読んでいただければ、C#でグローバル変数が無くても対応できる方法が分かります。
是非最後までお付き合いください。
C#におけるグローバル変数
まず結論から述べると、冒頭でも述べたとおりC#にグローバル変数はありません。こちらは開発元のMicrosoftのページで明記されています。
C#にはグローバル変数やグローバル メソッドはありません
引用元: Microsoft https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/classes-and-structs/index
基本的にはどの言語でもグローバル変数は多用を避けた方が良いもの。しかし、存在しないとなると困ってしまいますよね。
以降の章では、グローバル変数の代わりとして使える考え方について解説します。
グローバル変数相当の使い方をするには
グローバル変数が無いとなるとメソッドの戻り値で取得するしかないかと言うと、そうでもありません。C#にグローバル変数自体はありませんが、グローバル変数のように扱える方法はあります。
変数にstaticを付けて、直接取得できるようにする
変数をグローバル変数のように扱いたい場合、宣言時に「static」と記述します。staticを記述すると、その変数は静的メンバになります。
静的メンバとは、そのクラスに属するメンバである事を意味し、インスタンスを複数生成しても一つの値を共有する性質を持ちます。この値にアクセスすることにより、グローバル変数のように扱う事が可能になります。
それでは、実際にstaticを使った例を紹介します。
using System;
using System.Collections.Generic;
public class GlobalVariables {
    public static bool GlobalBool = true; //外部からアクセスできる変数
    public static List GlobalList = new List(); //外部からアクセスできるリスト
    public const string GlobalStr = "Default String"; //外部から参照できる定数
    private int LocalInt; //比較用: staticを使わない変数
    public GlobalVariables(int num)
    {
        LocalInt = num;
    }
    public void WritePrivateInt()
    {
        Console.WriteLine("PrivateInt: " + LocalInt);
    }
}
class Program {
    static void Main() {
        GlobalVariables Inst1 = new GlobalVariables(8);
        GlobalVariables Inst2 = new GlobalVariables(32);
        //staticじゃない値は、それぞれのインスタンスで別
        Inst1.WritePrivateInt();
        Inst2.WritePrivateInt();
        //staticはどちらのインスタンスも共通
        Console.WriteLine(GlobalVariables.GlobalBool); //「クラス名.変数名」となっている点に注意
        Console.WriteLine(GlobalVariables.GlobalStr);
        GlobalVariables.GlobalList.Add(128);
        Console.WriteLine(GlobalVariables.GlobalList[0]);
    }
}  
実行結果:
PrivateInt: 8 PrivateInt: 32 True Default String 128
ポイントとしては変数がstaticで宣言されている点と、静的メンバを参照する際は「クラス名.変数名」となる(「インスタンス名.変数名」ではない)点です。
これによって、グローバル変数さながらに扱うことが可能になります。
また、型についてもint, string, listなど、どれを使っても正常に動作していることが分かります。
static + プロパティを使う
グローバル変数のように扱う手段の一つが、プロパティを使う方法です。プロパティは、クラス内部では関数のように扱いますが、外部から利用する場合は変数のように扱うことができる機能です。
実際にプロパティを使った例を紹介します。
using System;
public class DataProperty {
    
    // 実装は外部から隠蔽(privateにしておく)
    private static int SampleProperty; // staticで変数を宣言
    // 変数の取得・変更用のプロパティ
    public int PropertyInt
    {
        set { SampleProperty = value; }
        get { return SampleProperty; }
    }
}
class Program {
    static void Main() {
        DataProperty p = new DataProperty();
        Console.WriteLine("値を取得します。");
        Console.WriteLine(p.PropertyInt); //プロパティの値を取得する
        Console.WriteLine("値をセットし再取得します。");
        p.PropertyInt = 32;
        Console.WriteLine(p.PropertyInt);
        Console.WriteLine("新しいインスタンスも生成し、値をセットします。");
        DataProperty p2 = new DataProperty();
        p2.PropertyInt = 100;
        Console.WriteLine("p2 = " + p2.PropertyInt);
        Console.WriteLine("p1 = " + p.PropertyInt); //p2の変更がp1に影響するのかを確認
    }
}
プロパティの実装の仕方は以下になります。
プロパティを記述する側
- 「アクセスレベル 型 プロパティ名」と宣言する
 - プロパティの中にはset{}とget{}を入れ、それぞれ渡された値の代入、変数の値を返す処理を記述する
 - setに値が渡される際、値が変数valueに入る
 
プロパティを利用する側
- 「インスタンス名.プロパティ名」でプロパティとのやり取りをする
 - 値を取得する際は、「インスタンス名.プロパティ名」で取得
 - 値を代入する際は、「インスタンス名.プロパティ名 = 値」でセットする
 
実行結果:
値を取得します。 0 値をセットし再取得します。 32 新しいインスタンスも生成し、値をセットします。 p2 = 100 p1 = 100
インスタンスが別でも、staticとなっている変数の値が同じになっていることが分かりますね。
まとめ
今回の記事では、以下の点について解説致しました。
- C#にはグローバル変数はない
 - グローバル変数のように扱える方法がある
 - 静的メンバを利用する
 
グローバル変数が無いという公式ドキュメントを見てちょっと焦ってしまいますが、それなりに対策を立てることが可能です。
ですので、C#は使いづらいなんて思わずにどんどん活用していってください!
  





