bucket-sort logo bucket-sort

プログラミングとインフラエンジニアリングの覚え書き

  • Posts
  • About
  • Contact
  1. Home
  2. All Posts
  3. [C#] delegate と event の仕組みを整理する

[C#] delegate と event の仕組みを整理する

Apr 1, 2026 C# , .NET bucket-sort

C# の event と delegate はセットで登場することが多いですが、どちらが何の役割を担っているのかが混在しやすいです。この記事ではまず delegate から順に整理し、event がなぜ必要なのかの流れで理解していきます。

delegate とは何か

delegate は、メソッドを変数として扱うための型 です。

通常、変数には int や string などの値を入れますが、delegate を使うとメソッドそのものを変数に入れて渡すことができます。

// delegate の型定義(引数と戻り値のシグネチャを指定する)
delegate void Notify(string message);

// この型に合うメソッドを用意する
void SendEmail(string message) => Console.WriteLine($"[Mail] {message}");
void WriteLog(string message)  => Console.WriteLine($"[Log]  {message}");

// delegate 変数に代入する
Notify handler = SendEmail;

// 呼び出す
handler("処理が完了しました");
// → [Mail] 処理が完了しました

handler という変数に SendEmail メソッドを入れて、後から呼び出しています。メソッドを直接呼ぶのと結果は同じですが、どのメソッドを呼ぶかを実行時に切り替えられるのがポイントです。

マルチキャスト delegate

delegate は += で複数のメソッドを登録でき、呼び出すと全員にまとめて通知できます。これを マルチキャスト と呼びます。

Notify handler = SendEmail;
handler += WriteLog;

handler("処理が完了しました");
// → [Mail] 処理が完了しました
// → [Log]  処理が完了しました

逆に -= で登録を解除することもできます。

handler -= WriteLog;

このマルチキャストの仕組みが、イベント通知の基盤になっています。

event キーワードの役割

delegate だけでも通知の仕組みは作れますが、外部のコードが自由に操作できてしまうという問題があります。

// delegate のままだと…
handler = null;          // 外部から全リスナーを消せてしまう
handler("勝手に呼べる"); // 外部から直接発火できてしまう

これを防ぐのが event キーワードです。event をつけると、

  • += / -=(登録・解除)は外部からできる
  • = null(上書き)や直接呼び出しは外部からできない

という制限がかかります。

public class Button
{
    // event として宣言する
    public event Notify? Clicked;

    public void Click()
    {
        // 発火は Button クラス内部からのみ
        Clicked?.Invoke("ボタンがクリックされました");
    }
}

外部からは登録だけできます。

var button = new Button();

button.Clicked += msg => Console.WriteLine($"[A] {msg}");
button.Clicked += msg => Console.WriteLine($"[B] {msg}");

button.Click();
// → [A] ボタンがクリックされました
// → [B] ボタンがクリックされました

event は「通知専用の delegate」という理解が正確です。

EventHandler と EventArgs の慣習

.NET では event の型として EventHandler を使うのが慣習です。

// EventArgs を継承してデータを持たせる
public class OrderEventArgs : EventArgs
{
    public int OrderId { get; init; }
    public string ProductName { get; init; } = "";
}

public class OrderService
{
    // EventHandler<T> を使う
    public event EventHandler<OrderEventArgs>? OrderPlaced;

    public void PlaceOrder(int id, string name)
    {
        // ... 注文処理 ...

        // 購読者に通知する
        OrderPlaced?.Invoke(this, new OrderEventArgs
        {
            OrderId = id,
            ProductName = name
        });
    }
}

受け取り側は次のように登録します。

var service = new OrderService();

service.OrderPlaced += (sender, e) =>
    Console.WriteLine($"[通知] 注文 {e.OrderId}: {e.ProductName}");

service.PlaceOrder(1001, "ノートPC");
// → [通知] 注文 1001: ノートPC

sender は通知を発行したオブジェクト、e がイベントデータです。この形は .NET のコアライブラリでも広く使われているため、慣習に合わせて書いておくと他の開発者にも読みやすくなります。

Func / Action との違い

delegate の宣言が面倒な場合は、.NET 組み込みの汎用 delegate である Action / Func が使えます。

型 意味
Action<T> 引数あり・戻り値なしの delegate
Func<T, TResult> 引数あり・戻り値ありの delegate
EventHandler<T> (object sender, T e) 形式の通知用 delegate

自前で delegate 型を定義するのは、特別なシグネチャが必要な場合に限られます。多くの場合は Action / Func / EventHandler で対応できます。

まとめ

  • delegate はメソッドを変数として扱う型。マルチキャストで複数登録できる
  • event は delegate に「外部から勝手に上書き・発火できない」制限を加えたもの
  • 通知を受け取る側は += で登録、-= で解除
  • .NET の慣習として EventHandler<TEventArgs> の形を使うのが一般的

event を理解すると、.NET の UI フレームワークや各種ライブラリのイベント購読がスムーズに読めるようになります。

C# .NET デザインパターン
← Pub/Sub パターンとは何か Laravel の Event / Listener で Pub/Sub を実装する →

Related Posts

  • Pub/Sub パターンとは何か Mar 31, 2026
  • [C#] Interlockedの使い方 Mar 27, 2026
  • [C#] ImmutableHashSet<T>の使い方 Mar 26, 2026
  • [C#] HashSet<T>の使い方 Mar 25, 2026

Table of Contents

  • delegate とは何か
  • マルチキャスト delegate
  • event キーワードの役割
  • EventHandler と EventArgs の慣習
  • Func / Action との違い
  • まとめ

Recent Posts

  • Laravel の Event / Listener で Pub/Sub を実装する Apr 2, 2026
  • [C#] delegate と event の仕組みを整理する Apr 1, 2026
  • Pub/Sub パターンとは何か Mar 31, 2026
  • PHP/Laravel で値の状態を判定するヘルパ関数まとめ Mar 30, 2026
  • Filament の dehydrated メソッドとは何か Mar 29, 2026

Categories

  • AWS27
  • C#22
  • .NET20
  • Laravel16
  • Linux12
  • Apache8
  • MySQL8
  • PHP8
  • DynamoDB6
  • Nginx5
  • WordPress4
  • インフラ4
  • Hugo3
  • セキュリティ3
  • .NET Framework1
  • Aurora1
  • Filament1
  • Git1
  • SQS1

Tags

  • AWS
  • C#
  • .NET
  • Laravel
  • PHP
  • MySQL
  • セキュリティ
  • Linux
  • Apache
  • Code Snippet
  • DynamoDB
  • NoSQL
  • PHP-FPM
  • RDS
  • DoS
  • Nginx
  • Windows
  • WordPress
  • パフォーマンス
  • 監視
  • Amazon Linux 2023
  • CMS
  • Docker
  • Ipset
  • Iptables
  • OPCache
  • Webサーバー
  • 認可
  • Aurora
  • Blade
Powered by Hugo & Explore Theme.