C# のシングルトンの決定版ガイド

C# では、シングルトンは、クラスのインスタンス化を単一のオブジェクトに制限する設計パターンです。これにより、アプリケーション全体でクラスのインスタンスが 1 つだけ存在することが保証され、そのインスタンスへのグローバル アクセスが提供されます。

シングルトンと使用上の注意

シングルトンはいくつかの理由で役立ちます。

  • グローバル アクセス: シングルトンは、クラスの単一のグローバルにアクセス可能なインスタンスを持つ方法を提供します。これは、オブジェクトへの参照を明示的に渡さずに、アプリケーションのさまざまな部分でデータや機能を共有する必要がある場合に有利です。
  • リソース共有: シングルトンは、データベース接続、スレッド プール、キャッシュ メカニズムなど、複数のオブジェクトまたはコンポーネント間で共有する必要があるリソースを管理するために使用できます。リソース管理をシングルトン内にカプセル化することで、共有リソースへのすべてのアクセスが集中ポイントを経由するようになり、効率的な調整が可能になり、リソースの競合が回避されます。
  • オブジェクト作成の制御: シングルトンを使用すると、クラスのインスタンス化を制御し、インスタンスが 1 つだけ作成されるようにすることができます。これは、リソースの制約により作成されるオブジェクトの数を制限したり、クラスに関連付けられた特定の動作を強制したりするために重要となる場合があります。
  • オンデマンド初期化: シングルトンはオンデマンドで初期化できます。つまり、インスタンスは最初にアクセスされたときにのみ作成されます。これは、オブジェクトの作成にコストがかかる場合、または実際に必要になるまで作成を遅らせる場合に、パフォーマンスにとって有益です。
  • 同期とスレッド セーフ: シングルトン実装には、ロックや二重チェック ロックなどの同期メカニズムを組み込んで、マルチスレッド環境でのスレッド セーフを確保できます。これは、複数のスレッドがシングルトン インスタンスに同時にアクセスしている場合の競合状態や矛盾した状態を回避するのに役立ちます。

シングルトンは、他のデザイン パターンと同様に、慎重に使用する必要があることに注意してください。これらは利点をもたらしますが、グローバルな状態と密結合も導入し、テストとメンテナンスがより困難になる可能性があります。特定のユースケースを考慮し、シングルトンが最適なソリューションであるかどうかを評価することが重要です。

シングルトンのセットアップ

C# でシングルトンを実装する例を次に示します。

public sealed class Singleton
{
    private static Singleton instance;
    private static readonly object lockObject = new object();

    private Singleton() { } // Private constructor to prevent instantiation from outside

    public static Singleton Instance
    {
        get
        {
            if (instance == null) // Check if the instance is null
            {
                lock (lockObject) // Use lock to ensure thread safety
                {
                    if (instance == null) // Double-check locking to avoid race conditions
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }

    // Other methods and properties
}

この例では、クラス 'Singleton' にはプライベート コンストラクターがあり、他のクラスがその新しいインスタンスを作成できないようにしています。このクラスは、'Instance' というパブリック静的プロパティを公開します。このプロパティは、クラスの単一インスタンスを作成して返す役割を果たします。'Instance' に初めてアクセスすると、変数 'instance' が null かどうかがチェックされ、null である場合は、新しいインスタンスの作成時にロックを使用してスレッドの安全性が確保されます。

後続の 'Instance' の呼び出しでは、新しいインスタンスを作成せずに既存のインスタンスが返されます。このアプローチでは、アプリケーション全体で 'Singleton' のインスタンスが 1 つだけ存在することが保証されます。

この場合、'Singleton' はシールされたクラス (クラス宣言の前のキーワード 'sealed' に注意してください) であり、継承したり基底クラスとして使用したりすることはできません。他のクラスの場合。クラスがシール済みとしてマークされると、そのクラスから他のクラスが派生できなくなります。

シングルトン インスタンスには次のようにアクセスできます。

Singleton singleton = Singleton.Instance;

このコードは、アプリケーション内のどこで呼び出されるかに関係なく、クラス 'Singleton' の単一インスタンスへの参照を与えます。

結論

C# のシングルトンは、アプリケーション全体でクラスの単一インスタンスの作成を可能にし、そのインスタンスへのグローバル アクセスを提供する設計パターンです。 これらは、アプリケーションのさまざまな部分でデータや機能を共有し、共有リソースを効率的に管理し、オブジェクトの作成を制御し、スレッドの安全性を確保する必要があるシナリオに役立ちます。 シングルトンにはオンデマンドの初期化を組み込むこともできます。この場合、インスタンスは最初にアクセスされたときにのみ作成され、実際に必要になるまで作成を延期することでパフォーマンス上の利点が得られます。 ただし、グローバル状態と密結合に関連するトレードオフと潜在的な欠点を考慮して、シングルトンを慎重に使用することが重要です。 シングルトンが最適なソリューションであるかどうかを判断するには、特定の使用例を慎重に検討する必要があります。