C#文法小知識(四)依頼delegate


delegateは、ネーミングメソッドまたは匿名メソッドをカプセル化するために使用できる参照タイプです.委託はC++の関数ポインタに似ている.しかし、依頼はタイプが安全で信頼できる.委任の適用については、委任と汎用委任を参照してください.
ここでは依頼のいくつかの使い方を紹介します.
簡単な依頼例:
public class TestDelegate
{
	public delegate void Delegate(object sender);
	private Delegate _delegate;
	public void SetDelegate(Delegate dlg)
	{
		_delegate = dlg;
	}
	public void InvokeDelegate()
	{
		if (_delegate == null) {
			return; 
		}
		_delegate.Invoke (this);
	}
}

委任インタフェースの実装:
public class TestListenerA
{
	static public void OnDelegateInvoked(object sender)
	{
		System.Console.WriteLine ("Listener A");
	}
}

使用方法:
		TestDelegate dlg = new TestDelegate();
		TestListenerA la = new TestListenerA ();
		dlg.SetDelegate (la.OnDelegateInvoked);
		dlg.InvokeDelegate ();
 
      
      (       ) 
        ,            。 C++         TestDelegate       。 
   
  

delegate , TestDelegate :

	public void AddListener(Delegate dlg)
	{
		_delegate += dlg;
	}
	public void RemoveListener(Delegate dlg)
	{
		_delegate -= dlg;
	}

これにより、TestDelegateに のコールバックを できます.
クラスを し、staticの を しました.
public class TestListenerB
{
	static public void EventHandler(object sender)
	{
		System.Console.WriteLine ("Listener B");
	}
}

delegateはこのように できます.
		TestDelegate dlg = new TestDelegate();
		TestListenerA la = new TestListenerA ();
		dlg.AddListener (la.OnDelegateInvoked);
		dlg.AddListener (TestListenerB.EventHandler);
		TestDelegate.Delegate lamdaDlg = ((object sender) => {
			System.Console.WriteLine ("Listener Lamda C");
		});
		dlg.AddListener (lamdaDlg);
		dlg.AddListener((object sender) =>
			{
				System.Console.WriteLine ("Listener Lamda D");
			});
		dlg.InvokeDelegate ();

delegateの を することもできます.
		dlg.RemoveListener (TestListenerB.EventHandler);
		dlg.RemoveListener (lamdaDlg);
		dlg.InvokeDelegate ();

これでTestListenerB.EventHandlerとlamdaDlgは び されなくなりました.
delegateをすべて することもできます.
		dlg.SetDelegate (null);

:
		dlg.AddListener (lamdaDlg);

ここで に うかもしれませんが、nullとlamdaDlgを しても はありませんか?
たちはこの を ってdelegateを く します.
すべてのdelegateがSystemから け がれていることを っています.MulticastDelegate、 はSystemから する.Delegate.
System.Delegateは クラス(abstract class)なので、いくつかの な はSystem.MulticastDelegateで われています.
ここでは に2つの CombineとRemoveを るが,この2つの はいずれも であり,この2つの はそれぞれCombineImplとRemoveImplを び したと できる.
CombineImplは の であり,RemoveImplは の である.
システムはDelegateとSystemMulticastDelegateにはGetInvocationListという があります.この はシステムを した.Delegate で、 には び しに するdelegateがあります.
は できるシステムMulticastDelegateでは、CombineImplを び すと しい がこのテーブルに され、RemoveImplを び すとターゲット がテーブルから されます.
delegateがoperator+を び すとSystemが び されると できる.DelegateのCombineメソッドはoperator-を び すとSystemを び す.DelegateのRemoveメソッド.delegateに を り てるとSystemが び されます.DelegateのCreateDelegateメソッド.
の に ると、nullとlamdaDlgが できるのはなぜですか?Combine がどのように されているのかを する はなく, な だけで できる.
_delegate += dlg;

:
_delegate = (TestDelegate.Delegate)System.Delegate.Combine (_delegate, dlg);