Day 67 のゴールと全体像
Day 67 では、C# の「仕組みを理解すると一気に世界が広がる」テーマ、イベントの基礎をじっくり学んでいきます。 今日のキーワードはこの2つです。
- イベント
- delegateとの関係
イベントは、ボタンがクリックされたとき、ファイルの読み込みが終わったとき、 ゲームで敵が倒されたとき…など、「何かが起きた瞬間」を扱うための仕組みです。
そして、そのイベントの裏側で動いているのが delegate(デリゲート) です。 ここを理解しておくと、C# のコードがぐっと“立体的”に見えるようになります。
この記事では、
- イベントとは何か
- delegate とイベントの関係
- 自作イベントの作り方
- イベントの発火と購読の流れ
- 実践的なテンプレート
を、ステップバイステップでかみ砕いて解説していきます。
イベントとは何かをイメージでつかむ
「何かが起きたら呼んでね」という仕組み
イベントは、ひと言でいうと 通知の仕組み です。
あるオブジェクトが「○○が起きたよ!」と知らせる → その通知を受け取った側が、登録しておいた処理を実行する
という流れで動きます。
たとえば、ボタンのクリックをイメージしてみてください。
- ボタン(イベントを発行する側)が「クリックされたよ!」と知らせる
- 登録していたメソッド(イベントを受け取る側)が呼ばれる
この「登録しておくメソッド」が delegate であり、 「通知を送る仕組み」が event です。
イベントが活躍する場面
イベントは、次のような場面でよく使われます。
- GUIアプリ
- ボタンが押された
- テキストが変更された
- ゲーム
- プレイヤーがダメージを受けた
- ステージクリア
- 非同期処理
- ダウンロード完了
- タスクの終了通知
「何かが起きた瞬間に反応したい」というとき、 イベントはとても自然な形でコードを組み立てることができます。
delegate とイベントの関係
delegate は「メソッドの型」
まずは、delegate の役割を整理しておきます。
delegate は、
「こういう形のメソッドを登録できますよ」という“メソッドの型”
です。
たとえば、
// string を受け取って、何も返さないメソッドを表す delegate 型
public delegate void Notify(string message);
C#これは、
- 引数:
string message - 戻り値:
void
という形のメソッドを表す「型」です。
この delegate 型を使うと、
public class Notifier
{
public Notify Handler; // メソッドを入れておける変数
}
C#のように、「メソッドを入れておく変数」を作ることができます。
event は「delegate を使った通知システム」
イベントは、この delegate をベースにして作られます。
public class Notifier
{
public delegate void Notify(string message);
// イベントの定義
public event Notify OnNotified;
}
C#ここでのポイントは、
Notifyが「イベントに登録できるメソッドの型」event Notify OnNotified;が「そのメソッドを登録しておくイベント」
という関係になっていることです。
つまり、
- delegate:メソッドの型
- event:その delegate を使って通知を送る仕組み
という構造になっています。
まずは delegate だけで「イベントっぽい動き」を見てみる
イベントの理解を深めるために、 まずは event を使わず、delegate だけで「イベント風の動き」を作ってみます。
using System;
class Program
{
// 通知用の delegate 型
delegate void Notify(string message);
static void Main()
{
// 通知を受け取るメソッドを登録
Notify notifier = OnNotified;
// 作業をして、終わったら通知する
DoWork(notifier);
}
// 長い作業をするメソッド
static void DoWork(Notify notify)
{
Console.WriteLine("作業中…");
System.Threading.Thread.Sleep(1000); // 1秒待つ(長い処理のイメージ)
// 作業完了を通知
notify("作業が完了しました!");
}
// 通知を受け取るメソッド
static void OnNotified(string message)
{
Console.WriteLine($"通知: {message}");
}
}
C#このコードでは、
Notifydelegate が「通知用メソッドの型」DoWorkが「通知を送る側」OnNotifiedが「通知を受け取る側」
という関係になっています。
ただし、このままだと、
- 誰でも
notifierを書き換えられる - 複数のメソッドを登録する仕組みがない
- 外部から勝手に
notify("…")を呼べてしまう
など、少し危うい状態です。
そこで登場するのが event です。
event を使って「安全な通知システム」にする
event の基本形
イベントは、delegate をベースにして次のように定義します。
public delegate void Notify(string message);
public event Notify OnCompleted;
C#この event を付けることで、
- 外部から勝手にイベントを発火できない
- 外部から勝手にイベントを消せない(
=で上書きできない) +=で複数のメソッドを登録できる
という、安全で扱いやすい仕組みになります。
イベントを自分で作ってみる
ここからは、 「イベントを持つクラス」 と 「イベントを購読する側」 を セットで作っていきます。
ステップ1:イベントを持つクラスを定義する
using System;
public class Worker
{
// 1. delegate 型の定義
public delegate void Notify(string message);
// 2. event の定義
public event Notify OnCompleted;
// 3. 作業をするメソッド
public void DoWork()
{
Console.WriteLine("作業中…");
System.Threading.Thread.Sleep(1000); // 1秒待つ
Console.WriteLine("作業が終わりました。");
// 4. イベントを発火(通知)
OnCompleted?.Invoke("作業が正常に完了しました。");
// OnCompleted が null でなければ Invoke する、という安全な書き方です。
}
}
C#ここでのポイントは、
Notifydelegate が「イベントに登録できるメソッドの型」event Notify OnCompleted;が「作業完了を通知するイベント」OnCompleted?.Invoke("…")が「イベントを発火するコード」
という構造になっていることです。
ステップ2:イベントを購読する側を作る
using System;
class Program
{
static void Main()
{
Worker worker = new Worker();
// イベント購読(登録)
worker.OnCompleted += OnWorkCompleted;
// 作業開始
worker.DoWork();
}
// イベントが発火されたときに呼ばれるメソッド
static void OnWorkCompleted(string message)
{
Console.WriteLine($"イベント受信: {message}");
}
}
C#ここでは、
worker.OnCompleted += OnWorkCompleted;- 「作業が終わったら
OnWorkCompletedを呼んでね」と登録している
- 「作業が終わったら
DoWork()の中でイベントが発火されると、OnWorkCompletedが呼ばれてメッセージを表示する
という流れになっています。
実行イメージ
作業中…
作業が終わりました。
イベント受信: 作業が正常に完了しました。
この「イベントを持つクラス」と「イベントを購読する側」の関係が、 イベントの基本パターンです。
イベントの流れを整理してみる
イベントの4ステップ
- delegate 型を定義するcsharp
public delegate void Notify(string message); - event を定義するcsharp
public event Notify OnCompleted; - イベントを発火する(通知する)csharp
OnCompleted?.Invoke("完了しました!"); - イベントを購読(登録)するcsharp
worker.OnCompleted += OnWorkCompleted;
この4ステップを押さえておくと、 イベントのコードがぐっと読みやすくなります。
イベントは複数のメソッドを登録できる
イベントの便利なところは、 複数のメソッドを登録できる ことです。
worker.OnCompleted += msg => Console.WriteLine("A: " + msg);
worker.OnCompleted += msg => Console.WriteLine("B: " + msg);
worker.OnCompleted += msg => Console.WriteLine("C: " + msg);
C#この状態でイベントが発火すると、
- A の処理
- B の処理
- C の処理
が、登録された順番にすべて呼ばれます。
これは、
「ひとつの出来事に対して、複数の反応をまとめて登録しておける」
というイメージです。
イベントのミニテンプレート
最後に、Day 67 で使える「イベントの基本テンプレート」をまとめておきます。
イベントを持つクラスのテンプレート
public class Something
{
// イベント用 delegate 型
public delegate void Notify(string message);
// イベントの定義
public event Notify OnHappened;
public void DoSomething()
{
Console.WriteLine("何かの処理をしています…");
// ここで何かが起きたと仮定
Console.WriteLine("何かが起きました!");
// イベント発火
OnHappened?.Invoke("Something のイベントが発生しました。");
}
}
C#イベントを購読する側のテンプレート
class Program
{
static void Main()
{
var s = new Something();
// イベント購読(ラムダ式で登録)
s.OnHappened += message =>
{
Console.WriteLine($"イベント受信: {message}");
};
// 処理を実行
s.DoSomething();
}
}
C#delegate と event の関係をもう一度まとめる
delegate
- 役割: メソッドの型を表す
- 「こういう形のメソッドを登録できますよ」という宣言
- 例:
public delegate void Notify(string message);
event
- 役割: delegate を使った通知システム
- 「登録されたメソッドを安全に呼び出す仕組み」
- 外部から勝手に発火できない(安全性アップ)
+=で複数のメソッドを登録できる
イメージ
- delegate:「招待状のフォーマット」
- event:「招待状を配って、集まった人たちに一斉に知らせる仕組み」
というようにイメージしてもらうと、 イベントの役割がぐっとつかみやすくなると思います。
Day 67 のまとめ
Day 67 では、
- イベントとは「何かが起きたときに呼ばれる通知の仕組み」であること
- delegate は「イベントに登録できるメソッドの型」であること
- event は「delegate を使った安全な通知システム」であること
- イベントは複数のメソッドを登録できること
- イベントの4ステップ(定義 → 発火 → 購読 → 実行)
を、例題コードとともに見てきました。
イベントは、GUI・ゲーム・非同期処理・ライブラリ設計など、 実践的なプログラミングのあらゆる場面で登場する、とても重要な概念です。
ぜひ、
- 自分でイベントを持つクラスを書いてみる
- 複数のメソッドをイベントに登録してみる
- ラムダ式でイベント購読を書いてみる
といった小さな練習を重ねながら、 イベントの仕組みを「自分の武器」として、 少しずつ体に馴染ませていっていただければうれしいです。
