event

eventはその名のとおりイベントを処理するために用意されたものです。イベントソースとなるクラスはeventを定義し、イベントを受け取りたいクライアントはそのクラスのeventに対して、自身の持つ関数を登録します。

たとえば、buttonクラスはclickedイベントを持ち、クライアントはOnClick()を定義し、それをbuttonクラスのclickedに登録します。

実際にコードを書くには、まずdelegateでイベント用の関数の型を定義します。イベントソースクラスはそのdelegateのeventを宣言し、クライアントはそのdelegate型の関数を定義し、eventに登録します。

using namespace System;
delegate void ClickHandler();
ref class button {
public:
    event ClickHandler^ Clicked;
    button() {
        btnForTest = this;
    }
public:
    void someoneclicked() {
        Clicked();
    }
    static button^ btnForTest;
};
ref class Client {
private:
    button^ btn;
public:
    Client() {
        btn = gcnew button;
        btn->Clicked += gcnew ClickHandler(this, &Client::OnClick);
    }
private:
    void OnClick() {
        Console::WriteLine("someone clicked.");
    }
};
int main()
{
    Client^ client = gcnew Client;
    button::btnForTest->someoneclicked();
    return 0;
}

上記の例において、buttonクラスの

event ClickHandler^ Clicked;

は以下のように書いても動作します。

ClickHandler^ Clicked;

しかしeventとすることによっていくつかの制約がかかります。一つはClickedのコールはbuttonしかできなくなります。またクライアントがClickedに対して許可された操作は += と -= のみとなり、Clickedに対して、Clicked()したり Clicked = nullptrしたりすることができなくなります。

Clickedはいろいろなクライアントが登録するので、勝手に実行したり、nullptrをセットされたりしたらまずいのです。