C#ラムダ式 基礎文法最速マスターや、プログラミングC# を眺めながら、C#のeventを試していました。
class MainClass
{
public class Hoge
{
// Actionの他に EventHandler<object o, EventArgs e> がある。
public event Action<string> ActionHandler;
// Actionは、 Action Action<T> Action<T1,T2> 〜 Action<T1...T16>まである。
// http://msdn.microsoft.com/ja-jp/library/system.action(v=vs.110).aspx
public void DoAction ()
{
if (this.ActionHandler != null) {
// 1回の呼び出しに見えるが、実際には登録されたイベント全てが呼ばれる
this.ActionHandler (@"call action.");
}
}
}
public static void Main (string[] args)
{
// ↓を参考にいろいろなイベント登録を試す
// http://www.atmarkit.co.jp/fdotnet/rapidmaster/rapidmaster_01/rapidmaster_01.html
//
Hoge hoge = new Hoge ();
// Action<string> へのいろいろなイベント追加方法
hoge.ActionHandler += m => Console.WriteLine (" event1 message=" + m);
hoge.ActionHandler += (m) =>{
Console.WriteLine (" event2 message=" + m);
};
hoge.ActionHandler += delegate(string m){
Console.WriteLine (" event3 message=" + m);
};
hoge.ActionHandler += ActionHandlr4;
hoge.DoAction ();
Console.WriteLine ();
// イベントの削除
hoge.ActionHandler -= ActionHandlr4; // これは削除出来る
// ラムダ式を指定いてもイベントは削除出来ない。同一かどうか判断つかないから当然
hoge.ActionHandler -= m => Console.WriteLine (" event1 message=" + m); // これは削除出来ない
hoge.DoAction ();
// クラスの外側から、eventを呼び出す事は出来ない
// ↓はコンパイルエラーになる。
// hoge.ActionHandlr ("hoge");
// ↓取り出す事も出来ない(コンパイルエラー)
// var actions = hoge.ActionHandler;
}
public static void ActionHandlr4(string m){
Console.WriteLine (" event4 message=" + m);
}
}
- イベントの登録
- +=演算子を使って複数登録できる
- 登録出来る形は、ラムダ式や関数、delegateキーワード指定等。
- ただしdelegateキーワードはラムダ式があるので使う場面は少なそう。
- イベントの削除
- -=演算子で削除できる。
- ラムダ式は、何らかの変数に代入(束縛?)して無いとイベントから削除できない。
- イベントはクラスの外側からはアクセスできない。
- += と -= でのアクセスに限定されている。
- アクセスしようとしたら、コンパイルエラーになる。
- クラスの内側からイベントを呼ぶ時、1回呼ぶだけに見えるが、登録されたイベント全てが呼び出されている。
- 順番については「登録順」に呼び出されているように見えるが、これに依存するロジックを作るとハマりそうな気がする。
- Actionには、引数無しから引数16個までのバリエーションがある。
- C#の"デリゲート"と、objcの"デリゲート"は、別の概念。
- C#のデリゲートは、"delegate"キーワードが用意されていて、「関数ポインタをオブジェクトで包んで、安全に使えるようにする仕組み」のように見える。
- 言語仕様に組み込まれている
- objcの"デリゲート"は、「あるクラスから各種判断を分離して別クラスに委譲するテクニック」と「委譲したクラスを参照するプロパティ名(delegate)」の事。
- テクニックというか慣習。
- C#のデリゲートは、"delegate"キーワードが用意されていて、「関数ポインタをオブジェクトで包んで、安全に使えるようにする仕組み」のように見える。