PHPやJSを通して、第一級関数の考え方や、JQueryの.on()と.trigger()といったイベント処理にも慣れているつもりの状態でC#のイベント処理実装をした。
公式やエンジニアのブログのサンプルをコピペして動かすことは出来たが、何がどうなって動いているのかがわからなかった。
きちんと理解するために情報を整理していく中で、断片的であるが以下のことを学んだ。
①DelegateとEventHandlerとActionはみんな仲間。EventHandlerとActionはDelegateの派生クラスなので。
https://docs.microsoft.com/en-us/dotnet/api/system.delegate?view=netframework-4.7
https://docs.microsoft.com/en-us/dotnet/api/system.eventhandler?view=netframework-4.7
https://docs.microsoft.com/en-us/dotnet/api/system.action?view=netframework-4.7
より、
Object->Delegate
Object->Delegate->EventHandler
Object->Delegate->Action
とそれぞれ派生している。EventHandlerとActionもみんなDelegate。
②Delegate とは "静的メソッドまたはクラス インスタンスとそのクラスのインスタンス メソッドを参照するデータ構造体"
そもそもDelegateってなんだっけ、ということで用語の確認。
https://msdn.microsoft.com/ja-jp/library/system.delegate(v=vs.110).aspx より。
Delegateは関数(メソッド)を参照しているものなんですね、という確認。
普通に関数を実行するように、Delegate型のインスタンスにも、 delegateInstance(); ってカッコ付けて書くことで、参照先の関数が実行されるというイメージ。多分。
③EventArgsクラスはObjectクラスから直接派生している小さなクラス
・Object->Delegate と派生している(https://docs.microsoft.com/en-us/dotnet/api/system.eventargs?view=netframework-4.7)
・EventArgsクラスにはコンストラクタ引数やデータをセット/保持するためのメソッド/フィールドが無い(https://msdn.microsoft.com/ja-jp/library/system.eventargs(v=vs.110).aspx)
EventArgsクラス自体は多くの役割を持ってなさそうだとドキュメントからわかったので、
「EventHandlerに渡されてきたEventArgsインスタンスがEventArgsクラスから派生してないままなら、イベント固有のデータが無いことがわかる」という役割だけを果たすクラスと考えてよさそう
だから逆に「EventArgsが派生された状態でEventHandlerに渡されてきたら、イベント固有のデータがある」ともいえる
まあなんというか結局 https://msdn.microsoft.com/ja-jp/library/5z57dxz2(v=vs.110).aspx のとおり。
④eventキーワードは、Delegateにラッパーをかけるように使う。
雑に言うと、eventキーワードは、delegateを特殊なdelegateにさせるためのキーワードっぽい。
「+=演算子での使用を強制」「宣言元からしか呼び出せない」という特殊なdelegate(=イベント)に。
eventキーワードの使い方を紹介するサンプルでは
public event EventHandler CountdownCompleted;
public event AlarmEventHandler Alarm;
の2パターンをよく見るが、このときEventHandlerもAlarmEventHandlerも、Delegateクラスである。
"AlarmEventHandler"Delegateが、引数に(object sender, EventArgs e)をとる形じゃない場合はどうなるのかが、ドキュメントから見つけられなかった。コンパイルエラーになるのか、別に問題ないのか。