2013-02-14 17 views
10

私が持っている:EventInfo.GetRaiseMethod()常にnull

event EventHandler MyEvent; 

MyEvent += new EventHandler(someHandler); 

if(this.GetEvent("MyEvent").GetRaiseMethod() == null) 
{ 
    // Always true... 
} 

しかし、なぜ?ハンドラを追加した後、GetRaiseMethod()someHandlerMethodInfoに設定しないでください。

答えて

9

これはC#の変種であり、raiseアクセサーをサポートしていません。追加と削除のみ。 VB.NET、F#、C++/CLIのような他の.NET言語はそれらをサポートしており、その中の "fire"というCLI仕様ではよく定義されています。

C#チームがそれをスキップした理由を説明することは難しいですが、私はそれについての良い説明は見たことがありません。純粋な推測:それは、誰も購読していないイベントのイベント引数を構築するコストを避けるという彼らの望みと関係があるかもしれない。 GUIフレームワークでは非常に一般的です。 C#プログラマーが標準的なraiseイベントパターンを書くだけでなく、nullをチェックするのを忘れたときにNREを診断することで、何十億という時間が失われていたはずです。 C#v6のelvis演算子(?.)はついにそれをより簡単にしました。

Anyhooでは、C#で書かれたコードを反映する場合、GetRaiseMethod()から何も取得できません。しかし、VB.NET、F#またはC++/CLIで書かれたときは常にnullではないでしょう。リバースでイベントを発生させる必要がある場合は、バッキングデリゲート変数を掘り下げる必要があります。これは苦しいことがあります。自動生成された追加/削除アクセサが使用されている場合、バッキング変数はイベントと同じ名前になり、BindingFlags.NonPublic |を使用してType.GetField()で取得することができます。 BindingFlags.Instance。

+0

VB.NETに慣れていないので、 'Event'を使ってVB.NETコードを書こうとしましたが、GetRaiseMethod()が何かを返すようなケースを取得しようとしました。私は 'AddHandler'文を試しましたが、' Handles'節も試しました。前者は実行時(C#のように)にイベントに登録するようですが、後者はコンパイル時に関係を宣言するという点でより有望です。私は 'GetRaiseMethod'で成功しませんでしたが、' Nothing'(null)を返します。 'GetRaiseMethod'がVB.NETから来るコードに対して自明ではないことを示す例をどのように作成すればよいですか? –

+0

私はそれを試してみればうまく動作します、あなたはそれについて質問をする必要があります。 –

+0

さて、私は新しいスレッドに質問を投稿しました。 –

3

raiseメソッドは、 "add"と "remove"に加えてCLI仕様で言及されているアクセサの1つですが、ほとんどのイベントは単にこの機能を実装していません。特に、C#はこれをサポートしていません - そうです:それは常にnullを返します。

+0

C#の仕様ではなく、CLIの仕様について説明しておきたいことがあります。 – svick