|
■No76992 (kiku さん) に返信
> ご回答ありがとうございます。
> すっきりしました。
ただし、『ラムダ式』や『匿名メソッド』を使う場合は注意して下さい。
この場合、「その1」の「 button1.Click -= delegate { … }; 」な手法では
解除できませんので、「その2」のようにデリゲート変数に保持しておき、
そのインスタンスを通じて -= する必要があります。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
class Program
{
static void Baz() { Console.WriteLine("Baz"); }
static void Main(string[] args)
{
var foo = new Action(Baz);
var bar = new Action(Baz);
Action x = delegate { };
Action y = delegate { };
// foo と bar は別のインスタンスだが、
// 参照しているメソッドは同一インスタンス
Console.WriteLine("foo is bar = " + ReferenceEquals(foo, bar));
Console.WriteLine("foo.Method is bar.Method = " + ReferenceEquals(foo.Method, bar.Method));
Console.WriteLine("x is y = " + ReferenceEquals(foo, bar));
Console.WriteLine("x.Method is y.Method = " + ReferenceEquals(x.Method, y.Method));
Console.WriteLine("==> 一回目 (未割当) ****");
Console.WriteLine("== 一回目のイベント呼びだし");
RaiseEvents(); // 無反応
Console.WriteLine("<===");
Console.WriteLine("==> 二回目 (割当) ****");
Sample += foo; // foo のみ登録
//Sample += bar;
Sample += new Action(delegate { Console.WriteLine("匿名メソッド"); });
Sample += () => { Console.WriteLine("ラムダ式"); };
Console.WriteLine("== 二回目のイベント呼びだし");
RaiseEvents(); // 登録した 3 つのハンドラが呼ばれる
Console.WriteLine("<===");
Console.WriteLine("==> 三回目 (解除) ****");
//Sample -= foo;
Sample -= bar; // foo ではなく bar を解除してみる
Sample -= new Action(delegate { Console.WriteLine("匿名メソッド"); });
Sample -= () => { Console.WriteLine("ラムダ式"); };
Console.WriteLine("== 三回目のイベント呼びだし");
RaiseEvents(); // Baz は解除されたが、匿名メソッドやラムダ式は解除されない
Console.WriteLine("<===");
Console.WriteLine("おしまい ****");
Console.Read();
}
#if CUSTOM_EVENT_TEST
static EventHandlerList delegates = new EventHandlerList();
static event Action Sample
{
add { delegates.AddHandler("SampleEvent", value); }
remove { delegates.RemoveHandler("SampleEvent", value); }
}
static void RaiseEvents()
{
Delegate ev = delegates["SampleEvent"];
if(ev != null) ev.DynamicInvoke();
}
#else
static event Action Sample;
static void RaiseEvents()
{
if (Sample != null) Sample.Invoke();
}
#endif
}
|