Categories: Cシャープ

C#のイベント完全解説!デリゲートとの違いから使い方まで初心者にもわかりやすく紹介

C#でアプリケーション開発を行う際に頻繁に登場する「イベント」。ボタンをクリックしたときや、タイマーが一定時間を経過したときなど、ユーザーやシステムからのアクションに応じて特定の処理を行いたい場面は多々あります。
しかし、「イベント」と「デリゲート」の違いや、どうやって自作クラスにイベントを組み込めばいいのか、初心者には少し難しく感じるかもしれません。
この記事では、C#におけるイベントの基本的な仕組みから使い方、自作イベントの作成方法まで、実例を交えながらわかりやすく解説します。


イベントとは何か?C#における役割

C#の「イベント」とは、あるオブジェクト内で特定のアクションが発生したことを他のオブジェクトに通知する仕組みです。たとえば、ボタンがクリックされたとき、テキストボックスの文字が変更されたときなどに処理を行う必要がある場面で活用されます。

イベントは「通知する側(イベント発行元)」と「受け取って処理する側(イベント購読者)」に分かれていて、疎結合な構造を実現できるのが特徴です。


デリゲートとイベントの違いを理解しよう

C#のイベントは、内部的にはデリゲート(delegate)という仕組みを利用しています。
デリゲートは「関数の参照を保持できる型」であり、イベントはそのデリゲートをラップして「他のクラスに通知する手段」として提供されているものです。

デリゲートの基本構文

public delegate void Notify();  // デリゲート型の定義

public class Notifier
{
public Notify OnNotify; // デリゲートのインスタンス
}

イベントの基本構文

public class Notifier
{
public event Notify OnNotify; // デリゲートをイベントとして宣言
}

「event」キーワードが付くことで、外部からの操作が制限され、安全に通知専用の機能として使うことができます。


実例:イベントを使った簡単な通知処理

ここでは、イベントの仕組みを使って、「ある条件を満たすと通知する」簡単な例を紹介します。

ステップ1:イベント発行クラスの作成

public class TemperatureMonitor
{
public delegate void TemperatureExceededHandler(double temp);
public event TemperatureExceededHandler OnTemperatureExceeded;

public void CheckTemperature(double currentTemp)
{
if (currentTemp > 30.0)
{
OnTemperatureExceeded?.Invoke(currentTemp);
}
}
}

ステップ2:イベントを購読するクラス

public class AlertSystem
{
public void ShowWarning(double temp)
{
Console.WriteLine($"警告:温度が高すぎます!現在の温度:{temp}度");
}
}

ステップ3:使用例

class Program
{
static void Main()
{
TemperatureMonitor monitor = new TemperatureMonitor();
AlertSystem alert = new AlertSystem();

monitor.OnTemperatureExceeded += alert.ShowWarning;

monitor.CheckTemperature(32.5); // ⇒ 警告メッセージが表示される
}
}

このように、イベントにメソッドを登録し、条件を満たしたときだけ実行される仕組みが作れます。


標準イベントパターン(EventHandlerの使い方)

.NETの標準的なイベント設計では、EventHandler または EventHandler<TEventArgs> を使うのが一般的です。

サンプル:標準イベントパターンの実装

public class DataSender
{
public event EventHandler<DataEventArgs> DataSent;

public void SendData(string data)
{
Console.WriteLine($"データ送信中: {data}");
DataSent?.Invoke(this, new DataEventArgs(data));
}
}

public class DataEventArgs : EventArgs
{
public string Data { get; }
public DataEventArgs(string data)
{
Data = data;
}
}

購読側

public class Logger
{
public void LogData(object sender, DataEventArgs e)
{
Console.WriteLine($"ログ:{e.Data}");
}
}

実行例

class Program
{
static void Main()
{
DataSender sender = new DataSender();
Logger logger = new Logger();

sender.DataSent += logger.LogData;
sender.SendData("Hello World!");
}
}

このように、イベントの引数に必要な情報を含めることで、より汎用的で拡張性のある通知ができます。


複数のメソッドをイベントに登録する方法

イベントには複数のメソッドを登録できます。これを「マルチキャストデリゲート」と呼びます。

monitor.OnTemperatureExceeded += alert.ShowWarning;
monitor.OnTemperatureExceeded += (temp) => Console.WriteLine($"ログ記録:{temp}度");

このように追加することで、イベントが発生した際に複数の処理が順番に呼び出されます。


イベントの削除と注意点

登録したイベントは以下のように削除できます。

monitor.OnTemperatureExceeded -= alert.ShowWarning;

また、イベントが null のまま Invoke() を呼び出すと NullReferenceException が発生するので、?.Invoke() を使うのが一般的です。


自作コントロールやライブラリにイベントを導入する意義

イベントは、ユーザーが作成するUIコンポーネントやツールライブラリにも柔軟に組み込むことができます。
「誰が何をするか」を分離できるため、保守性の高いコードを書くうえで非常に役立ちます。


まとめ

C#のイベントは、ユーザー操作やシステムの状態変化に応じて処理を呼び出すための強力な仕組みです。
デリゲートをベースにした仕組みでありながら、event キーワードによってセーフな通知方法として活用できる点が魅力です。

ポイントをまとめると:

  • イベントはデリゲートをラップした通知メカニズム
  • イベントの購読と解除が可能
  • EventHandler を使うと標準的な書き方ができる
  • 自作クラスやUIコンポーネントへの実装にも有効

イベントを理解することで、よりモダンで保守性の高いC#アプリケーションを開発できるようになります。まずは簡単なイベント処理から試してみましょう!

upandup

Web制作の記事を中心に、暮らし、ビジネスに役立つ情報を発信します。 アフィリエイトにも参加しています。よろしくお願いいたします。