イベントはデリゲートと同様に、 遅延バインディング メカニズムです。 実際、イベントはデリゲートの言語サポートに基づいて構築されています。
イベントは、何かが発生したことをオブジェクトが (システム内のすべての関心のあるコンポーネントに) ブロードキャストする方法です。 その他のコンポーネントは、イベントをサブスクライブし、イベントが発生したときに通知を受け取ることができます。
プログラミングの一部でイベントを使用した可能性があります。 多くのグラフィカル システムには、ユーザーの操作を報告するイベント モデルがあります。 これらのイベントは、マウスの動き、ボタンの押下、および同様の相互作用を報告します。 これは最も一般的なシナリオの 1 つですが、イベントが使用される唯一のシナリオではありません。
クラスに対して発生させるイベントを定義できます。 イベントを操作する際の重要な考慮事項の 1 つは、特定のイベントに登録されているオブジェクトがない可能性があることです。 リスナーが構成されていないときにイベントが発生しないようにコードを記述する必要があります。
イベントをサブスクライブすると、2 つのオブジェクト (イベント ソースとイベント シンク) 間の結合も作成されます。 イベント シンクにイベントに対する関心がなくなったとき、イベント ソースの受信登録を解除する必要があります。
イベント サポートの設計目標
イベントの言語設計は、次の目標を対象としています。
- イベント ソースとイベント シンクの間の最小限の結合を有効にします。 これら 2 つのコンポーネントは、異なる組織によって記述される場合があり、異なるスケジュールで更新される場合もあります。
- イベントをサブスクライブし、同じイベントのサブスクライブを解除するのは簡単です。
- イベント ソースでは、複数のイベント サブスクライバーをサポートする必要があります。 また、イベントサブスクライバーがアタッチされていない場合もサポートできる必要があります。
イベントの目標は、デリゲートの目標と似ていることがわかります。 そのため、イベント言語のサポートはデリゲート言語のサポートに基づいて構築されています。
イベントの言語サポート
イベントを定義し、イベントをサブスクライブまたはサブスクライブ解除するための構文は、デリゲートの構文の拡張です。
event
キーワードを使用してイベントを定義します。
public event EventHandler<FileFoundArgs>? FileFound;
イベントの型 (この例ではEventHandler<FileListArgs>
) はデリゲート型である必要があります。 イベントを宣言するときに従う必要がある規則があります。 通常、イベント デリゲート型には void 戻り値があります。 イベント宣言は、動詞または動詞句である必要があります。 イベントが発生した内容を報告する場合は、過去の時制を使用します。 現在の時制動詞 ( Closing
など) を使用して、起こりそうなことを報告します。 多くの場合、現在の時制を使用することは、クラスが何らかのカスタマイズ動作をサポートしていることを示します。 最も一般的なシナリオの 1 つは、キャンセルをサポートすることです。 たとえば、 Closing
イベントには、閉じる操作を続行するかどうかを示す引数を含めることができます。 その他のシナリオでは、呼び出し元がイベント引数のプロパティを更新して動作を変更できます。 イベントを発生させ、アルゴリズムが実行する次のアクションが提案されたことを示すことができます。 イベント ハンドラーは、イベント引数のプロパティを変更することで、別のアクションを要求する場合があります。
イベントを発生させる場合は、デリゲート呼び出し構文を使用してイベント ハンドラーを呼び出します。
FileFound?.Invoke(this, new FileFoundArgs(file));
デリゲートに関するセクションで説明したように、?.
演算子を使用すると、そのイベントのサブスクライバーがいない場合にイベントを発生させないようにすることが容易になります。
イベントをサブスクライブするには、 +=
演算子を使用します。
var fileLister = new FileSearcher();
int filesFound = 0;
EventHandler<FileFoundArgs> onFileFound = (sender, eventArgs) =>
{
Console.WriteLine(eventArgs.FoundFile);
filesFound++;
};
fileLister.FileFound += onFileFound;
ハンドラー メソッドには、通常、前のコードに示すように、プレフィックス 'On' の後にイベント名が続きます。
-=
演算子を使用して登録を解除します。
fileLister.FileFound -= onFileFound;
イベント ハンドラーを表す式のローカル変数を宣言することが重要です。 これで受信登録解除によりハンドラーが削除されます。 代わりにラムダ式の本文を使用した場合、アタッチされていなかったハンドラーの削除が試行され、何も起こりません。
次の記事では、一般的なイベント パターンと、この例のさまざまなバリエーションについて説明します。
.NET