私は最近、C# の「イベント」が実際にあることを理解するようになりました。正直、何でもないです。私の調査結果を要約すると: eventキーワードは、デリゲートにのみ適用される単純な修飾子です。
したがって、イベントのすべての「魔法」はデリゲートの操作です。それでおしまい。Microsoft のドキュメントをたくさん読みましたが、これほど簡潔にまとめられた文章はありません。私の発見を続けると、デリゲート、クラス、および構造体はすべて同じ「レベル」にあります。それらは「オブジェクト」を定義する方法です。タイプのように「オブジェクト」を意味するのではなく、カプセル化された「何か」の概念を意味します。オブジェクト指向プログラミングを言うときに「オブジェクト」という言葉がどのように使われるかのように。
とにかく、「オブジェクト」には特定の修飾子があります。たとえば、sealed、readonly、virtual、static など...このリストは、ここにあります。デリゲートの場合、eventと呼ばれる特別なものがあります。Event は、デリゲートがクラスの一部として宣言されたときに、イベントに与えられたアクセス修飾子に従ってaddメソッドとremoveメソッドのみを公開するようにします。これらのメソッドは、getおよびsetと同様の性質で定義されています。プロパティの。デリゲートの他の操作 (代入、読み取りアクセス、メソッド呼び出しなど) は、イベント デリゲートが宣言されたクラス内でのみ許可されます。私が興味深いと思うもう 1 つの点は、すべてのデリゲートにメソッド Invoke、BeginInvoke、および EndInvoke があるにもかかわらず、Visual Studio 内でそれらを表示するために移動することも、それらを説明するドキュメントを見つけることもできないことです...
わかった。以上のことをすべて理解した後、デリゲートへのアクセス方法を変更する以外に、イベント キーワードを使用する利点は何ですか? 多くの場合、イベント キーワードなしでデリゲートを宣言する方がよいようです。私が最近遭遇した状況は、2 つのイベントを含む抽象基本クラスを作成したいというものでした。この基本クラスから派生したクラスは、派生クラスに公開されているクラスの他のオブジェクトと同様に、イベントを独自のものとして使用できる必要があります (別名、派生クラスが別のクラスにない限り、プライベートではありません)。アセンブリであり、オブジェクトは internal として宣言されています)。
基本的に、派生クラスでこれらのイベントを独自のものとして使用したかったのです。これを行う唯一の方法は、派生クラスがイベントを発生できるように、イベントのバッキング変数を保護されたものとして公開することでした。コードを見ると、基本的にデリゲートを 2 回定義していたので、これはかなりばかげているように見えました。1 つは保護されたフィールドとして、もう 1 つはパブリック イベントとして。私は思った、
コンストラクターで Action の out パラメーターを持つ Event というクラスを作成した方がよいのではないでしょうか? 返されるアクションは、多くの人がデリゲートの拡張メソッドとして作成した Raise と同等であり、デリゲートが null かどうかを確認してから、デリゲートを呼び出します。Event の唯一のパブリック メソッドは、デリゲートを追加し、基になるデリゲートからそれらを削除するための Add と Remove です (+=、-=)。クラスは、これらのイベントを次のようなプロパティとして持つことができます。
public Event SomethingHappened { get; private set; }
そのクラスだけがイベントを再割り当てできるようにします。または、パブリックの読み取り専用フィールドも同様に効果的です。コンストラクターから返される out パラメーターは、クラスによって格納され、クラスがイベントを発生させたいときに呼び出されます。私はそれがばかげた回避策であることを知っていますが、それは仕事を終わらせ、イベントを引数として渡すだけでなく、基本クラスが保護されていると定義している場合、派生クラスが Raise メソッドを呼び出すことを許可します。
TLDR: