Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

イベントがnullとはどういうことか?

.NETにおいてイベントとは、System.MulticastDelegateのインスタンスである。
MulticastDelegateは参照型なので、ただ宣言しただけで中身を入れていなければnullである。
ここまでは問題ない。

疑問に思うのは、それがnullでなくなる瞬間はいつか、ということだ。
例えば、こうするとnullではなくなる。

button1.Click += new EventHandler( button1_Click );

ここで興味深いのは、Clickイベントはイベントのインスタンスであり、このコードを実行するまではnullであり、+=演算子は通常、既存のインスタンスに対して使うものだ(という先入観がある)ということだ。
同様に、-=演算子を使って、すべてのハンドラを除去すると、イベントインスタンスはnullになる。

+=も-=もC++から受け継いだ演算子である。
C++でこれらの演算子を実装するときには、「自身のインスタンスに対してもう一方の引数を加え/差し引き、自身のインスタンスを返す」というのが定石である。
だから、自身のインスタンスがnullならば使えないという気がする。
だが、定石ではあるが、絶対ではない。自身のインスタンスを返さなくともよいのだ。
そもそも、C#では演算子はすべてstaticであるため、「自身のインスタンス」などというものは無い(その場合は「第一引数に第二引数を足して/引いて、第一引数を返す」というのが直感的ではあるが、やはり絶対ではない)。

MulticastDelegateに対する+=、-=は、それぞれ、静的メソッドであるCombine、Removeに置き換えられる。
左辺が第一引数に、右辺が第二引数に渡され、結果が左辺に格納される。
Combineは第一引数がnullなら第二引数を返し、Removeは第一引数の呼び出しリストから第二引数のハンドラを除いた結果、呼び出しリストが空になればnullを返すという挙動を示す。
このため、これらの演算子の結果は、nullだったものが非nullになったり、nullでないものがnullになったりする。

当初は、nullとの比較はGetInvocationListが空であるかどうかに置き換えられると思っていた。空とnullは違うのだから、それはいかんだろうと思っていたのだが、調べてみたら以上の通りだった。
…空とnullは違うのだから、空になったらnullを返すというのもどうかとは思うのだが。

投稿日時 : 2007年3月22日 13:21

Feedback

# re: イベントがnullとはどういうことか? 2007/03/23 6:56 επιστημη

ふむ…

a += b;

t = a + b;
a = t;
と解釈されるんなら、a,b がnullでもなんとかなりますな。

# re: イベントがnullとはどういうことか? 2007/03/25 19:19 Sheile

>…空とnullは違うのだから、空になったらnullを返すというのもどうかとは思うのだが。
nullを返さないと
a += b
a -= b
をする前と後での整合性が。

初期状態がnullでなく空であるべきなのか。

# re: イベントがnullとはどういうことか? 2007/03/26 9:17 シャノン

> 初期状態がnullでなく空であるべきなのか。

うむ。
-= で空になったら null ではなく空として扱うなら、最初は空であるべきなのだろう。
すると、Delegate を値型にする必要がある…のはおかしいな。元々が関数ポインタなんだから。
じゃあ、あらかじめ new しておく必要がある、か。

あるいは、== null は GetInvocationList().Length == 0 と解釈されるようにコンパイラがごにょごにょする。
…整合性は取れるが気持ちが悪い。

ちなみに、イベントの場合は add アクセッサと remove アクセッサをカスタム実装することができるが、その場合は == null で判定すると怒られる。

# 68377.. Not so bad :) 2011/06/05 8:25 blogs.wankuma.com

68377.. Not so bad :)

# 68377.. He-he-he :) 2011/06/05 8:25 blogs.wankuma.com

68377.. He-he-he :)

# 68377.. Awesome :) 2011/07/02 14:09 8d19 porno ktz3

68377.. Awesome :)

# 68377.. Outstanding :) 2011/07/02 14:09 lnnh xxx jlny

68377.. Outstanding :)

タイトル
名前
Url
コメント