ラムダ式の寿命は?
これが私の問題ですbutton1.Click
。ラムダ式でサブスクライブされたイベントがあります。登録を解除する必要があるかどうかわかりません (匿名なので簡単ではありません)。または、接続されているコントロール(button1)と同じ寿命であるため、そうする必要はありませんか?
button1.Click += (s, e) => { /*Do something; */};
デリゲートの存続期間をもたらすすべての通常のCLRオブジェクトは、それを参照するものによって定義されます。あなたの場合、。button1
を介してのみ参照を保持しますClick
。その結果、。と同時にガベージコレクションに適切に利用できるようになりますbutton1
。特別な理由がない限り(つまり、ハンドラーを別のハンドラーに変更したい場合)、それを「解放」するために特別なことをする必要はありません。
ラムダ式はボタンに関連付けられているため、ボタンがメモリから破棄されない限り存続します。
登録を解除する必要があるかどうかわかりません (匿名なので簡単ではありません)。
ラムダ式は EventHandler デリゲートに保存できます。これにより、ラムダにアクセスしてイベントからサブスクライブを解除するオプションが提供されます。コードは次のとおりです。
EventHandler myEvent= (s, e) => { /*Do something; */};
//Subscribe
button1.Click += myEvent;
//Unsubscribe
button1.Click -= myEvent;
おそらく、このトピックに関する最良の説明はこちらです。イベントの登録を解除する必要がありますか?
イベント ハンドラーへの参照への参照は、ローカル変数でキャプチャすることで簡単に保持できます。
EventHandler click = (s, e) => { /* Do something; */ };
次に、次のようにアタッチできます。
this.button1.Click += click;
ハンドラーへの参照を保持するためにクラスレベルの変数を作成する必要があることが多いため、クリーンアップは少し難しい場合があります。これにより、コードがクラス全体に散らばってしまいます。
ただし、かなり簡単に処理する方法があります。次のように、クラスレベルのcleanup
アクションを作成して、すべてのクリーンアップ アクションをキャプチャします。
private Action cleanup = () => { };
これで、イベント ハンドラーをアタッチするコードを次のように 1 つのメソッドにうまく配置できます。
EventHandler click = (s, e) => { /* Do something; */ };
this.button1.Click += click;
cleanup += () => this.button1.Click -= click;
フォームの操作が完了したら、次のようにクリーンアップを非常に迅速に行うことができます。
cleanup();
すばらしいことに、あらゆる種類のクリーンアップ コードをこのアクション変数に追加できます。