デリゲート、イベント、およびこれら 2 つの機能の .NET 実装に関するスタック オーバーフローに関する非常に良い質問をいくつか見てきました。特に、「C# イベントは舞台裏でどのように機能しますか?」という 1 つの質問は、いくつかの微妙な点を非常によく説明する優れた回答を生み出しました。
上記の質問に対する答えは、次の点を指摘しています。
フィールドのようなイベントを宣言すると、コンパイラはメソッドとプライベート フィールド (デリゲートと同じ型) を生成します。クラス内で ElementAddedEvent を参照するときは、フィールドを参照しています。クラスの外では、フィールドを参照しています
同じ質問 (「フィールドのようなイベント」)からリンクされた MSDN の記事には、次のものが追加されています。
イベントを発生させるという概念は、イベントによって表されるデリゲートを呼び出すこととまったく同じです。したがって、イベントを発生させるための特別な言語構造はありません。
さらに詳しく調べたいので、イベントとデリゲートがコンパイルされる IL を表示するために、テスト プロジェクトを作成しました。
public class TestClass
{
public EventHandler handler;
public event EventHandler FooEvent;
public TestClass()
{ }
}
デリゲート フィールドhandler
とイベントFooEvent
はほぼ同じ IL コードにコンパイルされ、コンパイラによって生成されたFooEvent
フィールドへのアクセスをラップするメソッドがいくつか追加されることを期待していました。しかし、生成された IL は、私が期待したものとはまったく異なりました。
.class public auto ansi beforefieldinit TestClass
extends [mscorlib]System.Object
{
.event [mscorlib]System.EventHandler FooEvent
{
.addon instance void TestClass::add_FooEvent(class [mscorlib]System.EventHandler)
.removeon instance void TestClass::remove_FooEvent(class [mscorlib]System.EventHandler)
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
// Constructor IL hidden
}
.field private class [mscorlib]System.EventHandler FooEvent
.field public class [mscorlib]System.EventHandler handler
}
add
イベントは、コンパイラによって生成されたおよびメソッドを持つデリゲートにすぎないためremove
、IL でイベントがそれ以上のものとして扱われるとは思っていませんでした。ただし、 add メソッドと remove メソッドは、通常のメソッドとは 異なり.event
、で始まるセクションで定義されています。.method
.event
私の最終的な質問は次のとおりです。イベントがアクセサー メソッドを持つデリゲートとして単純に実装されている場合、 IL セクションを持つ意味は何ですか? .method
セクションを使用して、これなしで IL に実装できませんでしたか? と.event
同等.method
ですか?