イベントをリッスンする場合は、次のように言います。
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
このイベントの登録を解除するにはどうすればよいですか? それとも、メモリがリークするのを許しますか?
イベントをリッスンする場合は、次のように言います。
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
このイベントの登録を解除するにはどうすればよいですか? それとも、メモリがリークするのを許しますか?
匿名デリゲートのインスタンスに名前を付けます。
EventHandler<NewEventArg> handler = delegate(object sender, NewEventArgs e)
{
//some code
};
Subject.NewEvent += handler;
Subject.NewEvent -= handler;
イベントの登録を解除する必要がある場合は、イベント ハンドラーの匿名デリゲートを避けることをお勧めします。
これは、これをローカル メソッドに割り当てた方がよいケースの 1 つです。イベントから完全にサブスクライブを解除できます。
最初の呼び出しでハンドラーを削除するには:
//SubjectType Subject = ..... already defined if using (2)
EventHandler handler = null;
handler = delegate(object sender, EventArgs e)
{
// (1)
(sender as SubjectType).NewEvent -= handler;
// or
// (2) Subject.NewEvent -= handler;
// do stuff here
};
Subject.NewEvent += handler;
イベントのすべてのリスナーから登録を解除するためのメソッドを作成できます。これはまさにあなたが望むものではありませんが、役立つ場合があります。例(これは実際に機能します=)):
class Program {
static void Main(string[] args) {
A someClass = new A();
someClass.SomeEvent += delegate(object sender, EventArgs e) {
throw new NotImplementedException();
};
someClass.ClearEventHandlers();
someClass.FireEvent();
Console.WriteLine("No error.");
}
public class A {
public event EventHandler SomeEvent;
public void ClearEventHandlers() {
Delegate[] delegates = SomeEvent.GetInvocationList();
foreach (Delegate delegate in delegates) {
SomeEvent -= (EventHandler) delegate;
}
}
public void FireEvent() {
if (SomeEvent != null) {
SomeEvent(null, null);
}
}
}
}
匿名関数の名前が必要であり、その名前がスコープ内にある場合にのみ実行できます。
var handler = new EventHandler(delegate(object o, EventArgs e)
{
//do something...
};
Subject.NewEvent += handler;
// later on while handler is still in scope...
Subject.NewEvent -= handler;
漏洩以外の理由で登録を抹消する必要がありますか?
「または単にメモリのリークを許可する」ビットに関しては、Subject がガベージ コレクターによってクリーンアップされるときに、匿名デリゲートも同様にクリーンアップされる必要があるため、リークは発生しません。
いくつかの(あまりにも多くの)詳細でこれに入る(私の)別の質問があります:lambdas で使用するための弱いイベントハンドラーモデル。