12

私は持っている:

event EventHandler MyEvent;

MyEvent += new EventHandler(someHandler);

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

But why? After I add a handler, shouldn't GetRaiseMethod() be set to someHandler's MethodInfo?

4

2 に答える 2

11

これは C# の癖であり、raise アクセサーをサポートしていません。追加と削除のみ。VB.NET、F#、C++/CLI などの他の .NET 言語はそれらをサポートしており、CLI 仕様で明確に定義されており、その中で「fire」と名付けられています。

C# チームがそれをスキップした理由を説明するのは難しいです。純粋な憶測: 誰もサブスクライブしていないイベントのイベント引数を構築するコストを回避したいという彼らの願望と関係があるかもしれません. GUI フレームワークでは非常に一般的です。C# プログラマーが標準の raise イベント パターンを記述し、null をチェックするのを忘れたときに NRE を診断するために、何十万時間も無駄にしたに違いありません。C# v6の elvis 演算子 ( ?.) により、最終的に簡単になりました。

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

于 2013-02-15T02:07:25.023 に答える