読者です 読者をやめる 読者になる 読者になる

へっぽこびんぼう野郎のnewbie日記

けろけーろ(´・ω・`)!

「イベントリスナ=監視してる」ではない。C#でイベントリスナで詰まったのと、delegateとeventについて。

重要な概念

1.イベントリスナと、イベントハンドラはイコールではない。

イベントハンドラ ⊂ イベントリスナ

のような関係。

 

2. C#でイベントを理解するためには、delegateの概念の取得は必須である。

delegateよくわからないけどイベント使いたいから、よくわからないままでいいや。

→だめ、絶対

 

3.イベントって結局何

あるクラスの中のプロパティやメソッドが変更・使用された際に、その直前・直後に実行されるメソッド群のこと。

あるプロパティが変更されるまでそのクラスを監視しているわけでも、メソッドが発動されるまで監視しているわけでもない。

そんなに便利ではない。 

節子それイベントやない。モニタリングや。

 

(2014/07/20追記)4.delegateって何の役に立つの

このタイミングで動いてほしいというメソッドがある。

しかし今は定義したくない・できない。

こういうときにdelegateを使ってメソッドが使える余地を残しておくと、

あとでメソッドを追加して使用することができる。

イベントがまさにこれ。

delegateってなんやねん

必要とする前提知識

解説のためにstatic、非staticを多用します。

オブジェクトって何?という人はまずそちらを見ることをおすすめします。

参考URL

デリゲート - C# 入門

とても役に立った。

delegateは委譲するだけだよ」という摩訶不思議な文章。

いろいろなサイトを巡って見たけれど、どこのサイトでも、『delegateC言語でいう関数ポインタのようなものだよ』という文言から始まっている。

で、それをわかったものとして話を進め始めている様子だ。そこでおれは思った。

「関数ポインタ」ってなんだよ。

 

delegateの使い方について

まず、関数ポインタを説明する前にdelegateの使い方についてサンプルを見せます。

Output

Hoge

で、サンプルの解説をします。

 

3行目は飛ばして最後に説明します。

 

DelegateTestクラスについて。 

・7 MethodsAsClass型のオブジェクトを参照可能である、methodというフィールド、を定義します。 

・9 Mainメソッドです。ここからプログラムがスタートします。

・10 MethodsAsClassのオブジェクトを生成して、methodに代入しています。

・12 methodを使用します。(「オブジェクトに()をつけて使う」という謎なことをやっていると思われるかもしれませんがスルーしてください)

 

AnotherClassクラスについて。

・あとで使うためのメソッドを定義しているだけです。

 

MethodsAsClassについて。

メソッドをオブジェクトのように使うための、「クラスのような何か」です。

使いたいメソッドの引数と、delegateを定義する際の引数さえ一致していれば、どのようなメソッドもオブジェクトのように使えます。

これを「関数ポインタ」とか言ってるらしい。

メモリ上にあるメソッド(オブジェクトもどき)を、ポインタ(参照)してるだけだね!簡単だね!

 

これだけでは「なんでdelegateなんてもん使うの?」という感じだと思うので、その便利さを知ってもらうために次のサンプルを用意しました。

メソッドをまるでオブジェクトのように代入することができます。

 Output

Hoge

Hello

 

ちなみに

method = new MethodsAsClass(AnotherClass.OutHoge);

は、

method = AnotherClass.OutHoge;

のように略すことができます。

こんな感じ。

 

eventは、delegateしてるだけ

上記のdelegateを用いたものを応用してこのようなイベントもどきを作ります。

object senderとかEventArgs eとかは特に気にしなくてもいいです。

とりあえず引数があっても大丈夫ってことで、値を渡しています。

次はイベントを作ります。

 

まるで間違い探しのようになっていますが、違うところは

public static event MyEventHandler realEvent; 

です。

eventついただけ!!!!

 

結局同じことをやっています。

「え、じゃあeventキーワードってなんのためにあるの?!」という方もいるかもしれませんが、

eventキーワードをつけることによって、

定義したクラス以外から呼び出すことをできなくしたり、

定義したクラス以外からは=で代入することをできなくしたりします。

+= でイベントにメソッドを追加することや、-=でイベントからメソッドを削除することは、当然できます。

 

あとはイベント実装の話なのですが、

いろいろ書いて疲れたので割愛。

ていうか自分でも100%わかっていない感あるのでどや顔で書けないのが本音。

 

イベントについて勉強する前までは、

イベントハンドラとかいう便利なものがある」

「なんかクリックされてるかどうか監視してて、クリックされたら動くらしい!!」

という考え方だったけど、

 

別にそういうわけではなくて、

「あるクラスで、クリックするときに同時に使うメソッドを書いておく。そのクラスを継承したクラスでは、クリックをしたときに当然スーパークラスメソッドを使用する」

「このとき! delegateによって、スーパークラスメソッドを、派生クラスの中で定義することができる。」

「オブジェクトみたいなものになったスーパークラスメソッド(event MyEventHandler realEvent;)に、クリックしたときに発動させたいメソッドを追加する(realEvent += AnotherClass.OutHello;)」

「わたしがイベントハンドラだ」

 

というわけで、イベントは便利だけど、超万能の偉いひとというわけではない。

つらい。