C#
 Computer >> コンピューター >  >> プログラミング >> C#

【C#入門】デリゲートとイベントの違いを徹底解説!特徴と使い分けを比較

C#を学んでいると、「デリゲート(delegate)」と「イベント(event)」という2つの仕組みに出会います。どちらもメソッドへの参照を扱う点で似ていますが、役割や使い方には明確な違いがあります。この記事では、それぞれの特徴を整理しながら、両者の違いをわかりやすく解説します。

デリゲート(Delegate)とは

デリゲートは、メソッドへの参照を保持できる型であり、いわば「型安全な関数ポインタ」として機能します。主な特徴は以下の通りです。

  • 「delegate」キーワードを使用して宣言します。

  • 関数ポインタに相当し、実行時に1つ以上のメソッドへの参照を保持できます。

  • 独立したキーワードであり、イベントに依存しません。

  • Combine() メソッドや Remove() メソッドを持ち、呼び出しリスト(invocation list)へのメソッドの追加・削除を支援します。

  • メソッドの引数として渡すことができます。

  • 「=」演算子を使えば単一のメソッドを代入できます。

  • 「+=」演算子を使えば、複数のメソッドを1つのデリゲートに割り当てることができます。

イベント(Event)とは

イベントは、デリゲートをベースとした「通知機構」です。何かが起きたときに関連する処理(イベントハンドラ)へ通知を送るために使われます。主な特徴は以下の通りです。

  • 「event」キーワードを使用して宣言します。

  • デリゲートに依存する通知機構として定義され、デリゲートなしで作成することはできません。

  • デリゲートインスタンスをラップ(包み込む)したものと考えることができます。

  • デリゲートの利用者が、デリゲート自体やその呼び出しリストを勝手にリセットしてしまうことを防ぎます。

  • 呼び出しリストに対しては、ターゲット(ハンドラ)の追加または削除のみが許可されます。

  • 「EventInfo」クラスはイベントを検査(リフレクション)し、イベントハンドラのバインドを支援します。

  • AddEventHandler() メソッドと RemoveEventHandler() メソッドにより、呼び出しリストへのメソッドの追加・削除が行えます。

  • イベントは発生(raise)させることはできますが、メソッドの引数として渡すことはできません。

  • 「=」演算子はイベントには使用できません。

  • 「+=」および「-=」演算子を使って、イベントハンドラの追加・削除を行います。これらの操作は内部で AddEventHandler / RemoveEventHandler を呼び出しています。

コード例:デリゲートとイベントの基本的な使い方

using System;

// デリゲートの宣言
delegate void Notify(string message);

class Publisher
{
    // イベントの宣言(デリゲート型に基づく)
    public event Notify OnNotify;

    public void DoWork()
    {
        Console.WriteLine("処理を実行しました。");
        // イベントの発生
        OnNotify?.Invoke("処理が完了しました");
    }
}

class Program
{
    static void Main()
    {
        var publisher = new Publisher();

        // イベントハンドラの登録(+= 演算子)
        publisher.OnNotify += msg => Console.WriteLine($"通知: {msg}");

        publisher.DoWork();
    }
}

違いのまとめ(比較表)

項目デリゲートイベント
宣言キーワードdelegateevent
本質メソッドへの参照(関数ポインタ)デリゲートをラップした通知機構
依存関係独立しているデリゲートに依存
メソッドの引数として渡す可能不可
「=」による代入可能不可
「+=」「-=」の使用可能可能(ハンドラの追加・削除)
外部からの発生(raise)可能不可(宣言したクラス内のみ)

まとめ

デリゲートはメソッドへの参照そのものを柔軟に扱える汎用的な仕組みである一方、イベントはデリゲートを安全にカプセル化し、外部からの不正な上書きや直接呼び出しを防ぐための仕組みです。「メソッドを引数として渡したい」「コールバックを実装したい」場合はデリゲートを、「状態の変化を他のオブジェクトに通知したい」場合はイベントを使うのが基本の使い分けです。両者の違いを理解しておくことで、より安全で保守性の高いC#プログラムを設計できるようになります。

  1. Javaのコンストラクタとメソッドの違いとは?初心者向けに徹底解説

    コンストラクタはオブジェクトを生成・初期化するために使われる特別なメソッドである一方、メソッドは特定の処理(ステートメント)を実行するために使われます。一見似ている両者ですが、役割や動作には明確な違いがあります。ここでは、コンストラクタとメソッドの重要な違いを7つの観点から表形式で整理して解説します。No.項目コンストラクタメソッド1目的オブジェクトの生成と初期化を行うために使用される。特定の処理やステートメントを実行するために使用される。2呼び出し方システムによって暗黙的に自動呼び出しされる。プログラムコードの中で明示的に呼び出す必要がある。3呼び出しタイミングnewキーワードでオブジェクト

  2. 抽象クラスとインターフェースの違いを徹底解説

    抽象クラスとインターフェースの違いとはJavaなどのオブジェクト指向プログラミング言語では、抽象クラスとインターフェースはどちらも「抽象的な型」を定義するために使用されます。しかし、両者には明確な違いがあり、適切に使い分けることがプログラム設計の質を大きく左右します。抽象クラスの特徴抽象クラスは、インスタンスメソッドとしてデフォルトの動作(具体的な実装)を持つことができます。そのため、複数の子クラスで共有する共通処理をあらかじめ実装しておくことが可能です。また、コンストラクタやインスタンスフィールド(状態)を持つこともできます。インターフェースの特徴一方、インターフェースは定数とインスタンスメ