C#でシングルトンクラスの作り方

比較的大規模なシステムや、通信を行うシステムを作っていると
システム全体でこの機能を持つインスタンスを1つしか作りたくない
と思うケースに出会います。

たとえば

  • システム全体で他機器との通信状態を一元監視しているクラス
  • ロガーなど、システム全体で使う&ファイルアクセスなのであちこちで競合したら困る

のようなケースです。

昔ながらのC言語ではセマフォといって、プログラム間で資源の排他制御や同期を行うような仕組みが使われたりするのですが(セマフォに関してはまた後日解説します)
C#ではシングルトン(singleton)パターンというデザインパターンを使ってスマートに実現できます。
それにしても変な名前ですよね、シングルトン。

今回はそんなシングルトンパターンについて解説していきます。

それでは今回もまず完成形を掲載しましょう。

完成形の実例

public class SingletonClass
{
    //シングルトンクラスのインスタンス生成
    private static SingletonClass _instance = new SingletonClass();

    //コンストラクタ
    private SingletonClass()
    {
        //初期化処理
    }

    //外部からのインスタンス取得関数
    public static SingletonClass GetInstance()
    {
        //既に生成されているインスタンスへの参照を返す
        return _instance;
    }

    //外部から使いたい機能
    public void func()
    {
        //外部から使いたい機能の内容
    }
}

↑シングルトンパターンを実装したクラス

public class OtherClass
{
    //唯一のインスタンスへの参照をGetする
    SingletonClass singleInstance = SingletonClass.GetInstance();

    //SingletonClassの機能を使う
    singleInstance.func();
}

↑シングルトンクラスの機能を使う外部クラス

なんと、ポイントはたった2つ!

  • コンストラクタのスコープをprivateにする
  • インスタンスはクラス内でprivateとして生成し、外部からはGetInstance()メソッドで参照する

たったこれだけで実現できてしまうんですね!

コンストラクタをprivateにすることで、外部からのnew生成を禁止することができます。
同じくprivateなインスタンスはクラス内でのみ唯一生成されます。
あとは任意のクラスでGetInstance()メソッドを実行することで、上記で唯一生成されたインスタンスへの参照を取得することができます。

普段プログラミングしていてても「何に使うの……?」といまいちピンと来ないかもしれませんが、この記事の冒頭のように通信監視クラスやロガークラスを実装しようとすると、途端に意識しないといけなくなるのがインスタンスのこと。

シングルトンパターンを使いこなして、1段階上のレベルのエンジニアを目指しましょう!