8

C# でイベント ハンドラーを使用する方法を学ぼうとしていますが、次のコードで handler(this, e) が何をするのかわかりません。

public event EventHandler ThresholdReached;

protected virtual void OnThresholdReached(EventArgs e)
{
    EventHandler handler = ThresholdReached;
    if (handler != null)
    {
        handler(this, e);
    }
}

イベント (e) でイベント ハンドラー メソッド (this) を呼び出そうとしていませんか?

4

7 に答える 7

11

イベントに登録されているすべての登録済みイベント リスナーを呼び出しますThresholdReached

このhandler != nullチェックでは、少なくとも 1 つのリスナーがそのイベントに登録されていることを確認します。

C# 6.0 以降では、 Null Propagationを使用できます。

handler?.Invoke(this, e);

handler(this, e)登録されているすべてのイベントリスナーを呼び出します。イベントリスナーは、+=オペレーターの助けを借りてサブスクライブし、-=オペレーターを使用してそのイベントのサブスクライブを解除します。

this誰が ThresholdReached イベントを発生させたかをイベント リスナーに知らせます。イベントの送信者は誰でしたか。

eどのしきい値に達したかなど、ThresholdReached イベントに関するより有用な情報を含めることができるリスナー メソッドにも渡されるイベント引数です。

于 2012-08-31T14:41:42.603 に答える
1

これはThresholdReached、引数 sender=this および eventarguments = e でイベントを発生させています。実際、次と同じです。

public event EventHandler ThresholdReached;

protected virtual void OnThresholdReached(EventArgs e)
{
    if (ThresholdReached != null)
    {
        ThresholdReached(this, e);
    }
}

このイベントのリスナーがある場合。リスナー デリゲートを呼び出すだけです。

this.ThresholdReached += new EventHandler(Form1_ThresholdReached);

次に、このイベントが発生すると、パラメータを使用Form1_ThresholdReachedして関数が呼び出されます。thise

于 2012-08-31T14:44:16.167 に答える
1

この例のコードは、登録されているすべてのハンドラーをローカル変数handlerにコピーし、呼び出しリストが空でないことを確認し、コピーされた呼び出しリストのすべてのメンバーを引数thisおよびで呼び出しますe

現在の呼び出しリストのスナップショットを取得する理由は、デリゲートが不変であるためです。現在のマルチキャスト デリゲートへの参照を取得し、ハンドラーが追加または削除されると、バッキング フィールドは 2 つの不変のデリゲートから作成された新しいデリゲートを指します。

呼び出しリストをローカル変数にコピーする通常の理由は、ある種のスレッド セーフです。通常の nullity チェック (呼び出しリストが空でないことを確認する) と実際の呼び出しの間で、ハンドラーがサブスクライブ解除される可能性があります。ハンドラーなしで誤ってイベントを発生させ、NullReferenceExceptionがスローされます。

于 2012-08-31T15:31:01.763 に答える
0

handler の呼び出しは、別のオブジェクトまたはクラスでの関数呼び出しを表します。オブジェクトを作成すると、次のようなコードを記述できます。

obj.ThreasholdReached += new EventHandler(someFunction);

someFunctionそのクラスでは、このように定義されます

public someFunction(object sender, EventArgs e) {...}

元のオブジェクトのOnThreasholdReached関数は、ThreasholdReached ハンドラーに関数を割り当てた他のクラスにイベントを発行するものです。仲介者として使用handlerすることは、まったく不要な余分なステップです。あなたはまだ言っていますif ThreasholdReached != null、それは同じことです。

要約: このコード行handler(this, e)は、実際にsomeFunction(object sender, EventArgs e)は、オブジェクトの ThreasholdReached イベントに割り当てられたサブスクライバーへの呼び出しです。

于 2012-08-31T14:52:13.527 に答える
0

イベント (e) でイベント ハンドラー メソッド (this) を呼び出そうとしていませんか?

いいえ、文字通りではありません。EventArgse を使用してイベント ハンドラーを呼び出し、this送信者として使用しています。次のようにすることもできます。

if (ThresholdReached != null)
{
    ThresholdReached(this, e);
}

または、null チェックを回避するには:

public event EventHandler ThresholdReached = delegate { };

protected virtual void OnThresholdReached(EventArgs e)
{
    ThresholdReached(this, e);
}

しかし、@Oded が指摘したように、最初の部分はスレッドセーフではありませんEventHandler handler = ThresholdReached。ハンドラーのコピーを作成するためです。これについては、この質問でよりよく説明されています。

于 2012-08-31T14:41:42.733 に答える
0

handlerThresholdReachedあなたのイベントを指します。そのため、誰かがThresholdReachedイベントをサブスクライブしている場合、登録済みのハンドラーが引数thisおよびで呼び出されますe

于 2012-08-31T14:43:08.893 に答える
0

イベントのトリガーThresholdReachedです。自分自身への参照を渡す、this. でイベントに関する引数を渡しますe

于 2012-08-31T14:43:37.450 に答える