イベントのサブスクリプションとサブスクリプション解除を行う方法 (C# プログラミング ガイド)

別のクラスによってパブリッシュされるイベントが発生したときに呼び出されるカスタム コードを作成するときは、そのイベントをサブスクライブします。 たとえば、ユーザーがボタンをクリックしたらアプリケーションで何かを行うには、ボタンの click イベントをサブスクライブします。

Visual Studio IDE を使ってイベントをサブスクライブするには

  1. デザイン ビューに [プロパティ] ウィンドウが表示されない場合は、イベント ハンドラーを作成するフォームまたはコントロールを右クリックして、 [プロパティ] を選びます。

  2. [プロパティ] ウィンドウの [イベント] ボタンをクリックします。

  3. 作成するイベントをダブルクリックします (Load イベントなど)。

    Visual C# によって空のイベント ハンドラー メソッドを作成され、コードに追加されます。 または、コード ビューを使って手動でコードを追加することもできます。 たとえば、次のコード行では、Form クラスで Load イベントが発生すると呼び出されるイベント ハンドラー メソッドを宣言しています。

    private void Form1_Load(object sender, System.EventArgs e)
    {
        // Add your form load event handling code here.
    }
    

    イベントをサブスクライブするために必要なコード行も、プロジェクトの Form1.Designer.cs ファイルの InitializeComponent メソッドに自動的に生成されます。 次のようなコードです。

    this.Load += new System.EventHandler(this.Form1_Load);  
    

プログラムでイベントをサブスクライブするには

  1. シグネチャがイベントのデリゲート シグネチャと一致するイベント ハンドラー メソッドを定義します。 たとえば、イベントが EventHandler デリゲート型に基づいている場合は、次のコードがメソッド スタブを表します。

    void HandleCustomEvent(object sender, CustomEventArgs a)  
    {  
       // Do something useful here.  
    }  
    
  2. 加算代入演算子 (+=) を使って、イベントにイベント ハンドラーをアタッチします。 次の例では、publisher オブジェクトに RaiseCustomEvent という名前のイベントがあるものとします。 イベントをサブスクライブするには、サブスクライバー クラスがそのパブリッシャー クラスを参照する必要があることに注意してください。

    publisher.RaiseCustomEvent += HandleCustomEvent;  
    

    また、ラムダ式を使用してイベント ハンドラーを指定することもできます。

    public Form1()  
    {  
        InitializeComponent();  
        this.Click += (s,e) =>
            {
                MessageBox.Show(((MouseEventArgs)e).Location.ToString());
            };
    }  
    

匿名関数を使ってイベントをサブスクライブするには

後でイベントのサブスクリプションを解除する必要がない場合は、加算代入演算子 (+=) を使って匿名関数をイベント ハンドラーとしてアタッチできます。 次の例では、publisher オブジェクトに RaiseCustomEvent という名前のイベントがあり、CustomEventArgs クラスもある種の特別なイベント情報を保持するように定義されているものとします。 イベントをサブスクライブするには、サブスクライバー クラスがその publisher クラスを参照する必要があることに注意してください。

publisher.RaiseCustomEvent += (object o, CustomEventArgs e) =>
{  
  string s = o.ToString() + " " + e.ToString();  
  Console.WriteLine(s);  
};  

匿名関数を使ってイベントをサブスクライブした場合、簡単にはイベントのサブスクリプションを解除することはできません。 このシナリオでサブスクリプションを解除するには、イベントをサブスクライブするコードに戻り、匿名関数をデリゲート変数に格納した後、イベントにデリゲートを追加します。 コード内の後の時点でイベントのサブスクリプションを解除する必要がある場合は、イベントのサブスクライブに匿名関数を使わないことをお勧めします。 匿名関数について詳しくは、「ラムダ式」をご覧ください。

サブスクリプションの解除

イベントが発生したときにイベント ハンドラーが呼び出されないようにするには、イベントからサブスクリプションを解除します。 リソースのリークを防ぐには、サブスクライバー オブジェクトを破棄する前に、イベントのサブスクリプションを解除する必要があります。 イベントのサブスクリプションを解除するまで、パブリッシュ側オブジェクトでイベントの基盤になっているマルチキャスト デリゲートは、サブスクライバーのイベント ハンドラーをカプセル化するデリゲートへの参照を保持しています。 パブリッシュ側オブジェクトがその参照を保持している限り、ガベージ コレクションはサブスクライバー オブジェクトを削除しません。

イベントのサブスクリプションを解除するには

  • イベントのサブスクリプションを解除するには、減算代入演算子 (-=) を使います。

    publisher.RaiseCustomEvent -= HandleCustomEvent;  
    

    すべてのサブスクライバーがイベントのサブスクリプションを解除すると、パブリッシャー クラスのイベント インスタンスは null に設定されます。

関連項目