この章のテーマ §
eventキーワードとイベントについて学びます。イベントはオブジェクトの内部で起きたことを外部に通知するメカニズムです。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, クラスの基礎, 継承の基礎
解説 §
クラス等のメンバーにはイベントを含めることができます。イベントはクラスの内部で起きた出来事を外部に通知するために使用されます。たとえば、【ボタンが押された】【リストの選択項目が変わった】【タイマーが指定時間になった】などの出来事が発生した時、それを通知する手段となります。
イベントを使うのには、【イベントの作成】【イベントハンドラの追加】【イベントの発生】の3つの手順を踏まねばなりません。
イベントの作成にはeventキーワードを使います。データ型には、EventHandlerを使います。これには型引数があるものとないものがあります。型引数は、独自のイベント引数クラスを使う場合に使います。このサンプルソースではMyEventArgsというクラスを作って使っています。EventArgsに追加するものが何もないときは用意しなくても構いません。
イベントハンドラの追加には+=演算子を使います。これでイベントにイベント発生時に実行するコードを追加できます。また、イベントハンドラは複数追加することもできますので、既に追加済みかどうか意識せずに追加して構いません。追加されるメソッドは常に引数が2つです。一つ目はイベントを発生させたオブジェクト、2つめは指定したイベントの情報を持つオブジェクトです・
イベントの発生は、単純にイベントをメソッドのように呼び出すだけです。難しいことはありません。ただし、クラスの外からはイベントを発生できません。
罠の数々 §
- イベントはdelegateと紛らわしいが全く違う別個の機能なので勘違いしないようにしよう。イベントは出来事の通知を行うが、delegateは実行されるコードを保持する型を定義する
- イベントはWinFormアプリなどを作る時には必ずお世話になる基本的な機能だ。意識しておくと良いだろう。ただし、単にシンプルなアプリを書くだけならイベントはVisual Studuioなどが自動生成してくれるコードだけで用が足りて、特に意識しないで済むかも知れない
- イベントやイベントハンドラの指定方法は他にもあるが、EventHandlerを使う方法がガイドラインにも沿っていて望ましいだろう
- 通知を受け取る方法には、他に継承して特定メソッドをオーバーライドする方法もある
参考リンク §
イベント (C# プログラミング ガイド)
サンプルソース: kw_event §
var a = new SampleClass();
// イベントの登録
a.OnNotify += (sender, e) =>
{
Console.WriteLine($"オブジェクトaでイベント発生! 理由:{e.Message}");
};
a.SampleMethod();
// イベントの情報を持つクラス
public class MyEventArgs : EventArgs
{
public string? Message { get; set; }
}
// イベントを持つクラス
public class SampleClass
{
public event EventHandler<MyEventArgs>? OnNotify;
public void SampleMethod()
{
// イベント発生
if (OnNotify != null) OnNotify(this, new MyEventArgs() { Message = "SampleMethodが呼ばれました" }) ;
}
}
実行結果 §
オブジェクトaでイベント発生! 理由:SampleMethodが呼ばれました
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
イベントハンドラを追加するには+=演算子を使うが、削除するときはどうするのだろうか?
- イベントハンドラを取り除くことはできない
- イベントハンドラを取り除くときは-=演算子を使う
- イベントハンドラを取り除くときはRemoveメソッドを使う
- イベントハンドラを取り除くときはDeleteメソッドを使う
- イベントハンドラを取り除くときはClearメソッドを使う
[[解答]]