2012-04-02 12 views
3

イベントハンドラを一度呼び出すだけで、それを切り離したいと思います。私が書くことを試みた:最初に呼び出すときにハンドラを切り離す

EventHandler handler = (s, e) => 
{ 
    // Do something 
    // 
    // blabla 

    // Detach the handler 
    SizeChanged -= handler; 
}; 
SizeChanged += handler; 

しかしラインSizeChanged -= handlerに私はこのエラー

Use of unassigned local variable 'handler' 

を取得し、あなたは私が進むべき方法にidead持っていますか?ブーリアンフラグを使うことを考えましたが、ハンドラを切り離す方法が見つからない場合にのみ実行します。

答えて

3

これは実際にまだ割り当てられていないためです。名前付きのメソッドを作成してみてください。そうすれば、シンボルは事前ハンドリングとして知られています。

private void OnEvent(object sender, EventArgs e) 
{ 
    // Do something 

    AnEvent -= OnEvent; 
} 

private void RegisterOnce() 
{ 
    AnEvent += OnEvent; 
} 

私はまた、デタッチする時間を持っていない、正確に同じ時刻にイベントを呼び出すだけデタッチ後DoSmethingコードを実行することをお勧めしますと、いくつかのロック機構を実装し、場合にあなたはmultithradingている、複数のスレッドから防ぐことでしょうしたがって、すべて実行されます。

6

C#コンパイラは、まず結果を変数に代入する前に書いたラムダ式を作成します。したがって、ラムダが定義されている場合、ハンドラには値はありません。

以前はEventHandlerにnullの値を代入しても機能します。

それは閉鎖だとローカル変数は閉鎖に捕獲され、コールハンドラの時に正しい値を持つことになりますし、それが動作しますので:downvotingすべての人に

 EventHandler handler=null; 

     handler = (s, e) => 
     { 
      // Do something 
      SizeChanged -= handler; 
     }; 
     SizeChanged += handler; 

それは勝ちましたNullReferenceExceptionが発生します。ハンドラはクロージャでキャプチャされるローカル変数であるため、ラムダ内のハンドラの値はクロージャを含むメソッドで変更されると変更されます。私は実際に私のPC上でそれをテストし、それは完全に動作します。

+1

これを行うと、コールバックでnull ref例外が発生します。 –

+2

いいえ、試してください。ハンドラはクロージャでキャプチャされます。 – aKzenT

+2

ねえ、あなたもそれを試してみる前に私を投票しないでください!クロージャがどのように動作するかをお読みください。 – aKzenT

関連する問題