1

これまでのところ、c#の限定的な使用で、いくつかのイベントをサブスクライブしました。次の2つのコードスニペットが2つの異なる単語EventHandlerを使用しているのはなぜElapsedEventHandlerですか?

        myProcess = new Process();
        myProcess.StartInfo.FileName = @"notepad.exe";
        myProcess.Exited += new EventHandler(MyProcessExited);

に比べ:

        myTimer = new System.Timers.Timer(tickLength);
        myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);

これらの単語は、私が使用しているイベントのオブジェクトEventHandlerに固有のものですか?ElapsedEventHandlerまたは、「EventHandler」を使用する必要があるオブジェクトのセット全体と、「ElapsedEventHandler」を使用する必要がある別のオブジェクトのセットがありますか?(つまり、使用するオブジェクトのセットXxxxxxEventHandlerなど)

4

2 に答える 2

4

これらの単語 EventHandler と ElapsedEventHandler は、私が使用しているイベントを持つオブジェクトに固有のものですか?

この言葉は代表者の名前です。そして、それらは、イベントをそのイベントのサブスクライバーに発生させたオブジェクトから渡される情報に固有です。イベント、デリゲート、パラメーターの受け渡しについては、以下をお読みください。

C# のイベントは、オブジェクトに興味深いことが起こったときに、クラスがそのクラスのクライアントに通知を提供する方法です。イベントはデリゲートを使用して宣言されます。

したがって、オブジェクトで興味深いことが起こったことをクライアントに通知したい場合は、デリゲートを宣言できます。

public delegate void SomethingHappenedDelegate();

クラスでこのタイプのイベントを宣言します。

class Foo
{
    public event SomethingHappenedDelegate SomethingHappened;

    // other code, which raises SomethingHappened event
    // when something interesting happened
}

このクラスのクライアントが何か興味深いことが起こったという通知を受け取りたい場合は、SomethingHappened イベントをサブスクライブする必要があります。また、イベント ハンドラーの署名は、イベントの種類 (この場合は SomethingHappenedDelegate) と一致する必要があります。

static void Main(string[] args)
{
    Foo foo = new Foo();
    foo.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened);            
}

// this method should be: void MethodName()
static void Foo_SomethingHappened()
{
    // you notified, that something happened
}

クライアントに通知するときに追加のデータを渡す必要がある場合は、いくつかの引数を取る別のデリゲート タイプを使用する必要があります。たとえば、クライアントにメッセージを渡したい場合は、イベントのデリゲート タイプを変更します。

public delegate void SomethingHappenedDelegate(string message);

ここで、このデリゲート タイプに対応するようにイベント ハンドラーを変更する必要があります。

static void Foo_SomethingHappened(string message)
{
    // you notified, that something happened and you recieved a message
}

別の例として、イベントを発生させたオブジェクトのインスタンスと、いくつかの追加引数 message と time を渡したい場合:

public delegate void SomethingHappenedDelegate(object sender, string message, DateTime time);

次に、同じ署名を持つイベント ハンドラーが必要です。

static void Main(string[] args)
{
    Foo foo1 = new Foo();
    foo1.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened);
    Foo foo2 = new Foo();
    foo2.SomethingHappened += new SomethingHappenedDelegate(Foo_SomethingHappened); 
}

// we use same event handler for all SomethingHappened events
static void Foo_SomethingHappened(object sender, string message, DateTime time)
{
    Foo foo = sender as Foo; // now we get object, which raised event
    // and we can use message and time
}

したがって、すべてのイベントには何らかのデリゲートのタイプがあります。そのデリゲートの定義には、イベントを処理するメソッドを受け取るパラメーターが記述されています。コードでは、 Process.ExitedTimer.Elapsedの 2 つのイベントを使用します。これらのイベントがどのように定義されているか見てみましょう:

public event EventHandler Exited;
public event ElapsedEventHandler Elapsed;

ここでは、さまざまな種類のデリゲートを確認できます。

public delegate void EventHandler(object sender, EventArgs e);
public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);

定義からわかるように、これらのデリゲートの最初のパラメーター (送信者) は同じで、最後のパラメーターは異なります。したがって、これらのイベントのハンドラーも、これらのデリゲートと一致する別の署名を持つ必要があります。

なぜ 2 番目のパラメーターの名前が EventArgs で終わるのか疑問に思うかもしれません。何かが起こったことを他のオブジェクトに通知したい場合、C# には次の規則が存在します。

  • イベント名はSomethingHappened
  • クライアントが追加のデータを渡す必要がある場合、これらのデータはオブジェクトにカプセル化され、EventArgs クラスから派生しますSomethingHappenedEventArgs
  • イベント デリゲートはEventHandlerである必要があります(追加情報をクライアントに渡す必要がない場合)、ジェネリック型EventHandler<SomethingHappenedEventArgs>である必要があります。または、名前SomethingHappenedEventHandlerと署名が無効なカスタム デリゲートである必要があります (オブジェクト送信者、SomethingHappenedEventArgs e)。

詳細はこちらをご覧ください

于 2012-04-20T10:18:48.440 に答える
0

いいえ、イベント名はフレームワーク デザイナーの選択の問題です。特定のオブジェクトのイベントを表現するデリゲートに強く結び付けられています。

EventHandler の定義は次のとおりです。

[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);

ElapsedEventHandler の定義は次のとおりです。

public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);

ご覧のとおり、それらはさまざまなdelegateタイプです。

于 2012-04-20T08:19:13.143 に答える